home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 6 / QRZ Ham Radio Callsign Database - Volume 6.iso / pc / files / dsp / dspkgctr.z / dspkgctr / gcc / config / dsp56k.md < prev    next >
Encoding:
Text File  |  1992-06-08  |  96.6 KB  |  4,224 lines

  1. ;;- Machine description for the Motorola DSP56000/1 for GNU C compiler
  2. ;;   Copyright ( C ) 1988 Free Software Foundation, Inc.
  3. ;;
  4. ;;    $Header: /usr1/dsp/cvsroot/source/gcc/config/dsp56k.md,v 1.44 92/05/14 14:14:42 pete Exp $
  5. ;;      $Id: dsp56k.md,v 1.44 92/05/14 14:14:42 pete Exp $
  6. ;;
  7. ;; This file is part of GNU CC.
  8.  
  9. ;; GNU CC is free software; you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation; either version 1, or ( at your option )
  12. ;; any later version.
  13.  
  14. ;; GNU CC is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;; GNU General Public License for more details.
  18.  
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU CC; see the file COPYING.  If not, write to
  21. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  
  23. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  24.  
  25. ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
  26. ;;- updates for most instructions.
  27.  
  28. ;;  %letter escapes for operand printing. (via PRINT_OPERAND).
  29. ;;  %d - print the accumulator name, disregard MEM_IN_STRUCT kludge.
  30. ;;  %e - print 1 after accumulator operand. No affect on non-accum reg.
  31. ;;  %f - print x: or y: before memory reference operand.
  32. ;;  %g - print alternate of x or y half-register.
  33. ;;  %h - print 0 after accumulator operand.
  34. ;;  %i - strip the 0/1 off an x or y half-register.
  35. ;;  %j - n register associated with r register.
  36. ;;  %k - print 2 after accumulator operand.
  37. ;;  %m - print the source reg name, without a trailing 0 or 1.
  38. ;;  %o - print the accumulator name with a trailing 10.
  39.  
  40. ;;  %p - output this as a pointer size constant.
  41. ;;  %q - output this as an integer size constant.
  42. ;;  %r - output this as a long size constant.
  43.  
  44. ;;
  45. ;;  ...........................................................................
  46. ;;
  47. ;;          MOVES, LOADS, STORES
  48. ;;
  49. ;;  ...........................................................................
  50. ;;
  51.  
  52.     
  53. ;; allow a PSImode value to be loaded into any register, but preferentially
  54. ;; load it into an A register. The A must come last - otherwise we risk 
  55. ;; messing up the code that does subunion stuff.
  56.  
  57. ( define_expand "movpsi"
  58.   [ ( set
  59.       ( match_operand:PSI 0 "general_operand" "" )
  60.       ( match_operand:PSI 1 "general_operand" "" ))
  61.   ]
  62.   ""
  63.   "
  64. {
  65.     if ( MEM == GET_CODE ( operands[0] ) &&
  66.     ( MEM == GET_CODE ( operands[1] ) ||
  67.      CONSTANT_P ( operands[1] ) ||
  68.      CONST_DOUBLE == GET_CODE ( operands[1] )))
  69.     {
  70.     operands[1] = force_reg ( PSImode, operands[1] );
  71.     }
  72. }" )
  73.  
  74. ( define_insn ""
  75.   [ ( set
  76.       ( match_operand:PSI 0 "register_operand" "=*D,*S*DA,m,*S*DA,*S*DA" )
  77.       ( match_operand:PSI 1 "general_operand" "*S*D,*S*DA,*S*DA,m,i" ))
  78.   ]
  79.   ""
  80.   "*
  81. {
  82.     return move_pointer ( operands );
  83. }" "TRUE, FALSE" )
  84.  
  85. ( define_insn ""
  86.   [ ( set
  87.       ( match_operand:PSI 0 "general_operand" "=*D,*S*DA,m,*S*DA,*S*DA" )
  88.       ( match_operand:PSI 1 "register_operand" "*S*D,*S*DA,*S*DA,m,i" ))
  89.   ]
  90.   ""
  91.   "*
  92. {
  93.     return move_pointer ( operands );
  94. }" "TRUE, FALSE" )
  95.  
  96. ( define_expand "movqi"
  97.   [ ( set
  98.       ( match_operand:QI 0 "general_operand" "" )
  99.       ( match_operand:QI 1 "general_operand" "" ))
  100.   ]
  101.   ""
  102.   "
  103. {
  104.     if ( MEM == GET_CODE ( operands[0] ) &&
  105.     ( MEM == GET_CODE ( operands[1] ) ||
  106.      CONSTANT_P ( operands[1] ) ||
  107.      CONST_DOUBLE == GET_CODE ( operands[1] )))
  108.     {
  109.     operands[1] = force_reg ( QImode, operands[1] );
  110.     }
  111. }" )
  112.  
  113. ( define_insn ""
  114.   [ ( set
  115.       ( match_operand:QI 0 "register_operand" "=*D,*S,<>m,*S*D,*S*D" )
  116.       ( match_operand:QI 1 "general_operand" "*S*A*D,*S*A*D,*S*A*D,<>m,i" ))
  117.   ]
  118.   ""
  119.   "*
  120. {
  121.     return move_singleword ( operands );
  122. }" "TRUE, FALSE" )
  123.  
  124. ( define_insn ""
  125.   [ ( set
  126.       ( match_operand:QI 0 "general_operand" "=*D,*S,<>m,*S*D,*S*D" )
  127.       ( match_operand:QI 1 "register_operand" "*S*A*D,*S*A*D,*S*A*D,<>m,i" ))
  128.   ]
  129.   ""
  130.   "*
  131. {
  132.     return move_singleword ( operands );
  133. }" "TRUE, FALSE" )
  134.  
  135. ( define_expand "movsi"
  136.   [ ( set
  137.       ( match_operand:SI 0 "general_operand" "" )
  138.       ( match_operand:SI 1 "general_operand" "" ))
  139.   ]
  140.   ""
  141.   "
  142. {
  143.     if ( MEM == GET_CODE ( operands[0] ) &&
  144.     ( MEM == GET_CODE ( operands[1] ) ||
  145.      CONSTANT_P ( operands[1] ) ||
  146.      CONST_DOUBLE == GET_CODE ( operands[1] )))
  147.     {
  148.     operands[1] = force_reg ( SImode, operands[1] );
  149.     }
  150. }" )
  151.  
  152. ( define_insn ""
  153.   [ ( set
  154.       ( match_operand:SI 0 "register_operand" "=*D,*S,<>m,*S*D,*S*D" )
  155.       ( match_operand:SI 1 "general_operand" "*S*A*D,*S*A*D,*S*A*D,<>m,i" ))
  156.   ]
  157.   ""
  158.   "*
  159. {
  160.     return move_singleword ( operands );
  161. }" "TRUE, FALSE" )
  162.  
  163. ( define_insn ""
  164.   [ ( set
  165.       ( match_operand:SI 0 "general_operand" "=*D,*S,<>m,*S*D,*S*D" )
  166.       ( match_operand:SI 1 "register_operand" "*S*A*D,*S*A*D,*S*A*D,<>m,i" ))
  167.   ]
  168.   ""
  169.   "*
  170. {
  171.     return move_singleword ( operands );
  172. }" "TRUE, FALSE" )
  173.  
  174. ( define_expand "movdi"
  175.   [ ( set
  176.       ( match_operand:DI 0 "general_operand" "" )
  177.       ( match_operand:DI 1 "general_operand" "" ))
  178.   ]
  179.   ""
  180.   "
  181. {
  182.     if ( MEM == GET_CODE ( operands[0] ) &&
  183.     ( MEM == GET_CODE ( operands[1] ) ||
  184.      CONSTANT_P ( operands[1] ) ||
  185.      CONST_DOUBLE == GET_CODE ( operands[1] )))
  186.     {
  187.     operands[1] = force_reg ( DImode, operands[1] );
  188.     }
  189. }" )
  190.  
  191. ( define_insn ""
  192.   [ ( set
  193.       ( match_operand:DI 0 "register_operand" "=*D,*S,<>m,*D*S,*D*S" )
  194.       ( match_operand:DI 1 "general_operand" "*D*S,*D*S,*D*S,<>m,Gi" ))
  195.   ]
  196.   ""
  197.   "*
  198. {
  199.     return move_doubleword ( 0, operands );
  200. }" "TRUE, FALSE" )
  201.  
  202. ( define_insn ""
  203.   [ ( set
  204.       ( match_operand:DI 0 "general_operand" "=*D,*S,<>m,*D*S,*D*S" )
  205.       ( match_operand:DI 1 "register_operand" "*D*S,*D*S,*D*S,<>m,Gi" ))
  206.   ]
  207.   ""
  208.   "*
  209. {
  210.     return move_doubleword ( 0, operands );
  211. }" "TRUE, FALSE" )
  212.  
  213. ( define_expand "movsf"
  214.   [ ( set
  215.       ( match_operand:SF 0 "general_operand" "" )
  216.       ( match_operand:SF 1 "general_operand" "" ))
  217.   ]
  218.   ""
  219.   "
  220. {
  221.     if ( MEM == GET_CODE ( operands[0] ) &&
  222.     ( MEM == GET_CODE ( operands[1] ) ||
  223.      CONSTANT_P ( operands[1] ) ||
  224.      CONST_DOUBLE == GET_CODE ( operands[1] )))
  225.     {
  226.     operands[1] = force_reg ( SFmode, operands[1] );
  227.     }
  228. }" )
  229.  
  230. ( define_insn ""
  231.   [ ( set
  232.       ( match_operand:SF 0 "register_operand" "=*D,*S,<>m,*D*S,*D*S" )
  233.       ( match_operand:SF 1 "general_operand" "*D*S,*D*S,*D*S,<>m,G" ))
  234.   ]
  235.   ""
  236.   "*
  237. {
  238.     return move_doubleword ( 1, operands );
  239. }" "TRUE, FALSE" )
  240.  
  241. ( define_insn ""
  242.   [ ( set
  243.       ( match_operand:SF 0 "general_operand" "=*D,*S,<>m,*D*S,*D*S" )
  244.       ( match_operand:SF 1 "register_operand" "*D*S,*D*S,*D*S,<>m,G" ))
  245.   ]
  246.   ""
  247.   "*
  248. {
  249.     return move_doubleword ( 1, operands );
  250. }" "TRUE, FALSE" )
  251.  
  252. ( define_expand "movdf"
  253.   [ ( set
  254.       ( match_operand:DF 0 "general_operand" "" )
  255.       ( match_operand:DF 1 "general_operand" "" ))
  256.   ]
  257.   ""
  258.   "
  259. {
  260.     if ( MEM == GET_CODE ( operands[0] ) &&
  261.     ( MEM == GET_CODE ( operands[1] ) ||
  262.      CONSTANT_P ( operands[1] ) ||
  263.      CONST_DOUBLE == GET_CODE ( operands[1] )))
  264.     {
  265.     operands[1] = force_reg ( DFmode, operands[1] );
  266.     }
  267. }" )
  268.   
  269. ( define_insn ""
  270.   [ ( set
  271.       ( match_operand:DF 0 "register_operand" "=*D,*S,<>m,*D*S,*D*S" )
  272.       ( match_operand:DF 1 "general_operand" "*D*S,*D*S,*D*S,<>m,G" ))
  273.   ]
  274.   ""
  275.   "*
  276. {
  277.     return move_doubleword ( 1, operands );
  278. }" "TRUE, FALSE" )
  279.  
  280. ( define_insn ""
  281.   [ ( set
  282.       ( match_operand:DF 0 "general_operand" "=*D,*S,<>m,*D*S,*D*S" )
  283.       ( match_operand:DF 1 "register_operand" "*D*S,*D*S,*D*S,<>m,G" ))
  284.   ]
  285.   ""
  286.   "*
  287. {
  288.     return move_doubleword ( 1, operands );
  289. }" "TRUE, FALSE" )
  290.  
  291. ;;
  292. ;;  ...........................................................................
  293. ;;
  294. ;;          BLOCKMOVES
  295. ;;
  296. ;;  ...........................................................................
  297. ;;
  298.  
  299. ( define_expand "movstrsi"
  300.   [ ( parallel [ ( set ( match_operand:BLK 0 "memory_operand" "" )
  301.                ( match_operand:BLK 1 "memory_operand" "" ))
  302.          ( use ( match_operand:SI 2 "general_operand" "" ))
  303.          ( use ( match_operand:SI 3 "general_operand" "" )) ] )
  304.   ]
  305.   ""
  306.   "
  307. {
  308.     rtx op0_reg, op1_reg, cpy_reg;
  309.  
  310.     op0_reg = gen_reg_rtx ( PSImode );
  311.     emit_move_insn ( op0_reg, force_reg ( PSImode, XEXP ( operands[0], 0 )));
  312.     
  313.     op1_reg = gen_reg_rtx ( PSImode );
  314.     emit_move_insn ( op1_reg, force_reg ( PSImode, XEXP ( operands[1], 0 )));
  315.     
  316.     cpy_reg = gen_reg_rtx ( DImode );
  317.  
  318.     if ( CONST_DOUBLE == GET_CODE ( operands[2] ))
  319.     {
  320.     operands[2] = gen_rtx ( CONST_INT, VOIDmode, 
  321.                    CONST_DOUBLE_LOW ( operands[2] ));
  322.     }
  323.     
  324.     emit_insn (
  325.            gen_rtx ( PARALLEL, VOIDmode,
  326.             gen_rtvec ( 7,
  327.                    gen_rtx ( CLOBBER, VOIDmode, op0_reg ),
  328.                    gen_rtx ( CLOBBER, VOIDmode, op1_reg ),
  329.                    gen_rtx ( USE, VOIDmode, operands[2] ),
  330.                    gen_rtx ( CLOBBER, VOIDmode, cpy_reg ),
  331.                    gen_rtx ( SET, VOIDmode, operands[0],
  332.                         operands[1] ),
  333.                    gen_rtx ( USE, VOIDmode, op0_reg ),
  334.                    gen_rtx ( USE, VOIDmode, op1_reg ))));
  335.     DONE;
  336. }" )
  337.  
  338. ( define_insn ""
  339.   [ ( parallel [ ( clobber ( match_operand:PSI 0 "register_operand" "=A" ))
  340.          ( clobber ( match_operand:PSI 1 "register_operand" "=A" ))
  341.          ( use ( match_operand:SI 2 "immediate_operand" "i" ))
  342.          ( clobber ( match_operand:DI 3 "register_operand" "=*D*S" ))
  343.          ( set ( match_operand:BLK 4 "memory_operand" "" )
  344.                ( match_operand:BLK 5 "memory_operand" "" ))
  345.          ( use ( match_operand:PSI 6 "register_operand" "0" ))
  346.          ( use ( match_operand:PSI 7 "register_operand" "1" )) ] )
  347.   ]
  348. ""
  349. "*
  350. {
  351.     operands[8] = gen_label_rtx ( );
  352.  
  353.     if ( 'l' == memory_model )
  354.     {
  355.     if ( IS_SRC_OR_MPY_P ( REGNO ( operands[3] )))
  356.     {
  357.         return \"do    #%c2,%l8\;move    l:(%1)+,%m3\;move    %m3,l:(%0)+\\n%l8\";
  358.     }
  359.     else
  360.     {
  361.         return \"do    #%c2,%l8\;move    l:(%1)+,%o3\;move    %o3,l:(%0)+\\n%l8\";
  362.     }
  363.     }
  364.     else /* single mem space. */
  365.     {
  366.     RETURN_DSP ( \"do    #%c2,%l8\;move    @:(%1)+,%3\;move    %3,@:(%0)+\\n%l8\" );
  367.     }
  368. }" )
  369.  
  370. ;;
  371. ;;  ...........................................................................
  372. ;;
  373. ;;          ADDITIONS
  374. ;;
  375. ;;  ...........................................................................
  376. ;;
  377.  
  378. ;; We provide quick software emulation via a subroutine that emulates
  379. ;; a floating point instruction.
  380.  
  381. ( define_insn "adddf3"
  382.   [ ( set ( match_operand:DF 0 "general_operand" "=D" )
  383.           ( plus:DF ( match_operand:DF 1 "general_operand" "0" )
  384.                     ( match_operand:DF 2 "general_operand" "D" ))) 
  385.   ]
  386.   ""
  387.   "*
  388. {
  389.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  390.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  391.     
  392.     if ( op0_is_a )
  393.     {
  394.     if ( op2_is_a )
  395.     {
  396.         return \"jsr    fadd_aa\";
  397.     }
  398.     else
  399.     {
  400.         return \"jsr    fadd_ba\";
  401.     }
  402.     }
  403.     else
  404.     {
  405.     if ( op2_is_a )
  406.     {
  407.         return \"jsr    fadd_ab\";
  408.     }
  409.     else
  410.     {
  411.         return \"jsr    fadd_bb\";
  412.     }
  413.     }
  414. }" )    
  415.  
  416. ( define_insn "addsf3"
  417.   [ ( set ( match_operand:SF 0 "general_operand" "=D" )
  418.           ( plus:SF ( match_operand:SF 1 "general_operand" "0" )
  419.                     ( match_operand:SF 2 "general_operand" "D" ))) 
  420.   ]
  421.   ""
  422.   "*
  423. {
  424.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  425.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  426.     
  427.     if ( op0_is_a )
  428.     {
  429.     if ( op2_is_a )
  430.     {
  431.         return \"jsr    fadd_aa\";
  432.     }
  433.     else
  434.     {
  435.         return \"jsr    fadd_ba\";
  436.     }
  437.     }
  438.     else
  439.     {
  440.     if ( op2_is_a )
  441.     {
  442.         return \"jsr    fadd_ab\";
  443.     }
  444.     else
  445.     {
  446.         return \"jsr    fadd_bb\";
  447.     }
  448.     }
  449. }" )    
  450.  
  451. ;; Note that we MUST provide for inc/dec with a constant of one. The reload
  452. ;; pass may arbitrarily spill a regsiter post/pre inc/dec and will attempt to
  453. ;; perform the increment on the fly by itself. It does not consult the code
  454. ;; generator to see whether ( PSI <= PSI + CONST_INT ) is a valid insn.
  455.  
  456. ( define_insn "addpsi3"
  457.   [ ( set ( match_operand:PSI 0 "register_operand" "=*D,*A" )
  458.       ( plus:PSI 
  459.         ( match_operand:PSI 1 "register_operand" "0,0" )
  460.         ( match_operand:SI 2 "general_operand" "*D*S,i" )))
  461.   ]
  462.   ""
  463.   "*
  464. {
  465.     if ( which_alternative )
  466.     {
  467.     switch ( INTVAL ( operands[2] ))
  468.     {
  469.     case 0:
  470.         return \"\";
  471.         
  472.     case 1:
  473.         return \"move    (%0)+\";
  474.         
  475.     case -1:
  476.         return \"move    (%0)-\";
  477.         
  478.     default:
  479.         if ( load_n_reg_p ( operands[0], operands[2] ))
  480.         {
  481.         return \"move    #%p2,%j0\;move    (%0)+%j0\";
  482.         }
  483.         else
  484.         {
  485.         return \"move    (%0)+%j0\";
  486.         }
  487.     }
  488.     }
  489.     else
  490.     {
  491.     return \"add    %2,%0\";
  492.     }
  493. }" )
  494.  
  495. ;; we need this extra shape because addition commutes. 
  496.  
  497. ( define_insn ""
  498.   [ ( set ( match_operand:PSI 0 "register_operand" "=*D,*A" )
  499.       ( plus:PSI 
  500.         ( match_operand:SI 1 "general_operand" "*D*S,i" )
  501.         ( match_operand:PSI 2 "register_operand" "0,0" )))
  502.   ]
  503.   ""
  504.   "*
  505. {
  506.     if ( which_alternative )
  507.     {
  508.     switch ( INTVAL ( operands[2] ))
  509.     {
  510.     case 0:
  511.         return \"\";
  512.         
  513.     case 1:
  514.         return \"move    (%0)+\";
  515.         
  516.     case -1:
  517.         return \"move    (%0)-\";
  518.         
  519.     default:
  520.         if ( load_n_reg_p ( operands[0], operands[2] ))
  521.         {
  522.         return \"move    #%p1,%j0\;move    (%0)+%j0\";
  523.         }
  524.         else
  525.         {
  526.         return \"move    (%0)+%j0\";
  527.         }
  528.     }
  529.     }
  530.     else
  531.     {
  532.     return \"add    %1,%0\";
  533.     }
  534. }" )
  535.  
  536. ;; this insn is here because insn_extract does not detect commutable operands.
  537.  
  538. ( define_insn ""
  539.   [ ( set ( match_operand:PSI 0 "register_operand" "=*D" )
  540.       ( plus:PSI 
  541.         ( match_operand:SI 1 "register_operand" "*D*S" )
  542.         ( match_operand:PSI 2 "register_operand" "0" )))
  543.   ]
  544.   ""
  545.   "add    %1,%0" )
  546.  
  547. ( define_insn "addsi3"
  548.   [ ( set ( match_operand:SI 0 "register_operand" "=*D" )
  549.           ( plus:SI ( match_operand:SI 1 "register_operand" "0" )
  550.                     ( match_operand:SI 2 "register_operand" "*S*D" ))) 
  551.   ]
  552.   ""
  553.   "*
  554. {
  555.     if ( REGNO ( operands[2] ) == REGNO ( operands[0] ))
  556.     {
  557.     return \"asl    %0\";
  558.     }
  559.     else
  560.     {
  561.     return \"add    %2,%0\";
  562.     }
  563. }" )
  564.  
  565. ;;( define_insn ""
  566. ;;  [ ( set ( match_operand:SI 0 "register_operand" "=*D" )
  567. ;;     ( plus:SI ( match_operand:SI 1 "register_operand" "%0" )
  568. ;;               ( match_operand:PSI 2 "register_operand" "*S*D" ))) 
  569. ;;  ]
  570. ;;  ""
  571. ;;  "*
  572. ;;{
  573. ;;    if ( REGNO ( operands[2] ) == REGNO ( operands[0] ))
  574. ;;    {
  575. ;;    return \"asl    %0\";
  576. ;;    }
  577. ;;    else
  578. ;;    {
  579. ;;    return \"add    %2,%0\";
  580. ;;    }
  581. ;;}" )
  582.  
  583. ( define_insn "adddi3"
  584.   [ ( set ( match_operand:DI 0 "register_operand" "=*D" )
  585.           ( plus:DI ( match_operand:DI 1 "register_operand" "0" )
  586.                     ( match_operand:DI 2 "register_operand" "*S*D" ))) ]
  587.   ""
  588.   "*
  589. {
  590.     if ( IS_SRC_OR_MPY_P ( REGNO ( operands[2] )))
  591.     {
  592.     return \"add     %i2,%0\";
  593.     }
  594.     else
  595.     {
  596.     if ( REGNO ( operands[2] ) == REGNO ( operands[0] ))
  597.     {
  598.         return \"asl    %0\";
  599.     }
  600.     else
  601.     {
  602.         return \"add    %2,%0\";
  603.     }
  604.     }
  605. }" )
  606.  
  607. ;;
  608. ;;  ...........................................................................
  609. ;;
  610. ;;          SUBTRACTIONS
  611. ;;
  612. ;;  ...........................................................................
  613. ;;
  614.  
  615. ;; We provide quick software emulation via a subroutine that emulates
  616. ;; a floating point instruction.
  617.  
  618. ( define_insn "subdf3"
  619.   [ ( set ( match_operand:DF 0 "general_operand" "=D" )
  620.           ( minus:DF ( match_operand:DF 1 "general_operand" "0" )
  621.                      ( match_operand:DF 2 "general_operand" "D" ))) 
  622.   ]
  623.   ""
  624.   "*
  625. {
  626.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  627.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  628.     
  629.     if ( op0_is_a )
  630.     {
  631.     if ( op2_is_a )
  632.     {
  633.         return \"clr    a\";
  634.     }
  635.     else
  636.     {
  637.         return \"jsr    fsub_ba\";
  638.     }
  639.     }
  640.     else
  641.     {
  642.     if ( op2_is_a )
  643.     {
  644.         return \"jsr    fsub_ab\";
  645.     }
  646.     else
  647.     {
  648.         return \"clr    b\";
  649.     }
  650.     }
  651. }" )    
  652.  
  653. ( define_insn "subsf3"
  654.   [ ( set ( match_operand:SF 0 "general_operand" "=D" )
  655.           ( minus:SF ( match_operand:SF 1 "general_operand" "0" )
  656.                      ( match_operand:SF 2 "general_operand" "D" ))) 
  657.   ]
  658.   ""
  659.   "*
  660. {
  661.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  662.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  663.     
  664.     if ( op0_is_a )
  665.     {
  666.     if ( op2_is_a )
  667.     {
  668.         return \"clr    a\";
  669.     }
  670.     else
  671.     {
  672.         return \"jsr    fsub_ba\";
  673.     }
  674.     }
  675.     else
  676.     {
  677.     if ( op2_is_a )
  678.     {
  679.         return \"jsr    fsub_ab\";
  680.     }
  681.     else
  682.     {
  683.         return \"clr    b\";
  684.     }
  685.     }
  686. }" )    
  687.  
  688. ;; There are really two ways that subtraction can be used with pointers:
  689. ;; 1) PSI <= PSI - SI, and 2) SI <= PSI - PSI. Because of the way that the
  690. ;; GNU CC is structured in optabs.c, subtraction type (1) must be labeled as
  691. ;; subpsi3. Version 1.7 of optabs.c has code that, when turned on, will allow
  692. ;; you use type (2) as subpsi3. Currently, the shape for type (2) should
  693. ;; never be used: c-typeck.c converts the operands of a (2) to SImode before
  694. ;; the subtraction. This has no effect on us currently, however, if we should
  695. ;; try to use the address alu for PSImode adds and subtracts, it will.
  696.  
  697. ;; Addendum: the shape for (2) could actually be generated by the DSP loop
  698. ;; optimization code in computing the number of loop iterations.
  699.  
  700. ;; Note that we MUST provide for inc/dec with a constant of one. The reload
  701. ;; pass may arbitrarily spill a regsiter post/pre inc/dec and will attempt to
  702. ;; perform the increment on the fly by itself. It does not consult the code
  703. ;; generator to see whether ( PSI <= PSI + CONST_INT ) is a valid insn.
  704.  
  705. ( define_insn "subpsi3"
  706.   [ ( set ( match_operand:PSI 0 "register_operand" "=*D,*A" )
  707.       ( minus:PSI
  708.         ( match_operand:PSI 1 "register_operand" "0,0" )
  709.         ( match_operand:SI 2 "general_operand" "*D*S,i" )))
  710.   ]
  711.   ""
  712.   "*
  713. {
  714.     if ( which_alternative )
  715.     {
  716.     switch ( INTVAL ( operands[2] ))
  717.     {
  718.     case 0:
  719.         return \"\";
  720.         
  721.     case 1:
  722.         return \"move    (%0)-\";
  723.         
  724.     case -1:
  725.         return \"move    (%0)+\";
  726.         
  727.     default:
  728.         if ( load_n_reg_p ( operands[0], operands[2] ))
  729.         {
  730.         return \"move    #%p2,%j0\;move    (%0)-%j0\";
  731.         }
  732.         else
  733.         {
  734.         return \"move    (%0)-%j0\";
  735.         }
  736.     }
  737.     }
  738.     else
  739.     {
  740.     return \"sub    %2,%0\";
  741.     }
  742. }" )
  743.  
  744. ( define_insn ""
  745.   [ ( set ( match_operand:SI 0 "register_operand" "=*D" )
  746.       ( minus:PSI 
  747.         ( match_operand:PSI 1 "register_operand" "0" )
  748.         ( match_operand:PSI 2 "register_operand" "*D*S" )))
  749.   ]
  750.   ""
  751.   "sub    %2,%0" )
  752.  
  753. ( define_insn "subsi3"
  754.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  755.      ( minus:SI ( match_operand:SI 1 "register_operand" "0" )
  756.                 ( match_operand:SI 2 "register_operand" "*S*D" ))) ]
  757.   ""
  758.   "*
  759. {
  760.     if ( REGNO ( operands[2] ) == REGNO ( operands[0] ))
  761.     {
  762.     return \"clr    %0\";
  763.     }
  764.     else
  765.     {
  766.     return \"sub    %2,%0\";
  767.     }
  768. }" )
  769.  
  770. ( define_insn "subdi3"
  771.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  772.      ( minus:DI ( match_operand:DI 1 "register_operand" "0" )
  773.                 ( match_operand:DI 2 "register_operand" "*S*D" )))
  774.   ]
  775.   ""
  776.   "*
  777. {
  778.     if ( IS_SRC_OR_MPY_P ( REGNO ( operands[2] )))
  779.     {
  780.     return \"sub     %i2,%0\";
  781.     }
  782.     else
  783.     {
  784.     if ( REGNO ( operands[2] ) == REGNO ( operands[0] ))
  785.     {
  786.         return \"clr    %0\";
  787.     }
  788.     else
  789.     {
  790.         return \"sub    %2,%0\";
  791.     }
  792.     }
  793. }" )
  794.  
  795. ;;
  796. ;;  ...........................................................................
  797. ;;
  798. ;;          MULTIPLICATIONS AND DIVISIONS
  799. ;;
  800. ;;  ...........................................................................
  801. ;;
  802.  
  803. ;; We provide quick software emulation via a subroutine that emulates
  804. ;; a floating point instruction.
  805.  
  806. ( define_insn "muldf3"
  807.   [ ( set ( match_operand:DF 0 "general_operand" "=D" )
  808.           ( mult:DF ( match_operand:DF 1 "general_operand" "0" )
  809.                     ( match_operand:DF 2 "general_operand" "D" ))) 
  810.   ]
  811.   ""
  812.   "*
  813. {
  814.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  815.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  816.     
  817.     if ( op0_is_a )
  818.     {
  819.     if ( op2_is_a )
  820.     {
  821.         return \"jsr    fmpy_aa\";
  822.     }
  823.     else
  824.     {
  825.         return \"jsr    fmpy_ba\";
  826.     }
  827.     }
  828.     else
  829.     {
  830.     if ( op2_is_a )
  831.     {
  832.         return \"jsr    fmpy_ab\";
  833.     }
  834.     else
  835.     {
  836.         return \"jsr    fmpy_bb\";
  837.     }
  838.     }
  839. }" )    
  840.  
  841. ( define_insn "mulsf3"
  842.   [ ( set ( match_operand:SF 0 "general_operand" "=D" )
  843.           ( mult:SF ( match_operand:SF 1 "general_operand" "0" )
  844.                     ( match_operand:SF 2 "general_operand" "D" ))) 
  845.   ]
  846.   ""
  847.   "*
  848. {
  849.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  850.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  851.     
  852.     if ( op0_is_a )
  853.     {
  854.     if ( op2_is_a )
  855.     {
  856.         return \"jsr    fmpy_aa\";
  857.     }
  858.     else
  859.     {
  860.         return \"jsr    fmpy_ba\";
  861.     }
  862.     }
  863.     else
  864.     {
  865.     if ( op2_is_a )
  866.     {
  867.         return \"jsr    fmpy_ab\";
  868.     }
  869.     else
  870.     {
  871.         return \"jsr    fmpy_bb\";
  872.     }
  873.     }
  874. }" )    
  875.  
  876. ;; We have two shapes for mac+ and two shapes for mac-, because the mult may
  877. ;; turn up as either operand of the plus/minus.
  878.  
  879. ( define_insn ""
  880.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  881.       ( plus:SI ( match_operand:SI 1 "register_operand" "0" )
  882.             ( mult:SI ( match_operand:SI 2 "register_operand" "%S" )
  883.                   ( match_operand:SI 3 "register_operand" "R" ))))
  884.   ]
  885.   ""
  886.   "*
  887. {
  888.     if ( MEM_IN_STRUCT_P ( insn ))
  889.     {
  890.     if ( RTX_UNCHANGING_P ( insn ))
  891.     {
  892.         return \"mac    +%2,%3,%0\";
  893.     }
  894.     return \"mac    +%2,%3,%0\;asr    %0\;move    %h0,%0\";
  895.     }
  896.     else if ( RTX_UNCHANGING_P ( insn ))
  897.     {
  898.     return \"move    %0,%h0\;asl    %0\;mac    +%2,%3,%0\";
  899.     }
  900.     return \"move    %0,%h0\;asl    %0\;mac    +%2,%3,%0\;asr    %0\;move    %h0,%0\";
  901. }" )
  902.  
  903. ( define_insn ""
  904.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  905.       ( plus:SI ( mult:SI ( match_operand:SI 1 "register_operand" "%S" )
  906.                   ( match_operand:SI 2 "register_operand" "R" ))
  907.             ( match_operand:SI 3 "register_operand" "0" )))
  908.   ]
  909.   ""
  910.   "*
  911. {
  912.     if ( MEM_IN_STRUCT_P ( insn ))
  913.     {
  914.     if ( RTX_UNCHANGING_P ( insn ))
  915.     {
  916.         return \"mac    +%1,%2,%0\";
  917.     }
  918.     return \"mac    +%1,%2,%0\;asr    %0\;move    %h0,%0\";
  919.     }
  920.     else if ( RTX_UNCHANGING_P ( insn ))
  921.     {
  922.     return \"move    %0,%h0\;asl    %0\;mac    +%1,%2,%0\";
  923.     }
  924.     return \"move    %0,%h0\;asl    %0\;mac    +%1,%2,%0\;asr    %0\;move    %h0,%0\";
  925. }" )
  926.  
  927.  
  928. ( define_insn ""
  929.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  930.       ( minus:SI ( match_operand:SI 1 "register_operand" "0" )
  931.              ( mult:SI ( match_operand:SI 2 "register_operand" "%S" )
  932.                    ( match_operand:SI 3 "register_operand" "R" ))))
  933.   ]
  934.   ""
  935.   "*
  936. {
  937.     if ( MEM_IN_STRUCT_P ( insn ))
  938.     {
  939.     if ( RTX_UNCHANGING_P ( insn ))
  940.     {
  941.         return \"mac    -%2,%3,%0\";
  942.     }
  943.     return \"mac    -%2,%3,%0\;asr    %0\;move    %h0,%0\";
  944.     }
  945.     else if ( RTX_UNCHANGING_P ( insn ))
  946.     {
  947.     return \"move    %0,%h0\;asl    %0\;mac    -%2,%3,%0\";
  948.     }
  949.     return \"move    %0,%h0\;asl    %0\;mac    -%2,%3,%0\;asr    %0\;move    %h0,%0\";
  950. }" )
  951.  
  952. ;; we have a quick (breaks calling convention rules) subr. act as an inst.
  953.  
  954. ( define_insn "muldi3"
  955.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  956.           ( mult:DI ( match_operand:DI 1 "register_operand" "0" )
  957.                     ( match_operand:DI 2 "register_operand" "D" ))) 
  958.   ]
  959.   ""
  960.   "*
  961. {
  962.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  963.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  964.     
  965.     if ( op0_is_a )
  966.     {
  967.     if ( op2_is_a )
  968.     {
  969.         return \"jsr    lmpy_aa\";
  970.     }
  971.     else
  972.     {
  973.         return \"jsr    lmpy_ba\";
  974.     }
  975.     }
  976.     else
  977.     {
  978.     if ( op2_is_a )
  979.     {
  980.         return \"jsr    lmpy_ab\";
  981.     }
  982.     else
  983.     {
  984.         return \"jsr    lmpy_bb\";
  985.     }
  986.     }
  987. }" )    
  988.  
  989.  
  990. ;; normal, boring mults follow.
  991.  
  992. ( define_insn "mulsi3"
  993.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  994.       ( mult:SI ( match_operand:SI 1 "register_operand" "%S" )
  995.             ( match_operand:SI 2 "register_operand" "R" ))) 
  996.   ]
  997.   ""
  998.   "*
  999. {
  1000.     if ( RTX_UNCHANGING_P ( insn ))
  1001.     {
  1002.     return \"mpy    %2,%1,%0\";
  1003.     }
  1004.     return \"mpy    %2,%1,%0\;asr    %0\;move    %h0,%0\";
  1005. }" )
  1006.  
  1007.  
  1008. ( define_insn "umulsi3"
  1009.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1010.       ( umult:SI ( match_operand:SI 1 "register_operand" "%S" )
  1011.              ( match_operand:SI 2 "register_operand" "R" )))
  1012.   ]
  1013.   ""
  1014.   "mpy    %2,%1,%0;asr    %0;move    %h0,%0" )
  1015.  
  1016. ;; We provide quick software emulation via a subroutine that emulates
  1017. ;; a floating point instruction.
  1018.  
  1019. ( define_insn "divdi3"
  1020.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1021.           ( div:DI ( match_operand:DI 1 "register_operand" "0" )
  1022.                    ( match_operand:DI 2 "register_operand" "D" ))) 
  1023.   ]
  1024.   ""
  1025.   "*
  1026. {
  1027.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  1028.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  1029.     
  1030.     if ( op0_is_a )
  1031.     {
  1032.     if ( op2_is_a )
  1033.     {
  1034.         return \"clr    a\;move    #>1,a0\";
  1035.     }
  1036.     else
  1037.     {
  1038.         return \"jsr    ldiv_ba\";
  1039.     }
  1040.     }
  1041.     else
  1042.     {
  1043.     if ( op2_is_a )
  1044.     {
  1045.         return \"jsr    ldiv_ab\";
  1046.     }
  1047.     else
  1048.     {
  1049.         return \"clr    b\;move    #>1,b0\";
  1050.     }
  1051.     }
  1052. }" )    
  1053.  
  1054. ( define_insn "moddi3"
  1055.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1056.           ( mod:DI ( match_operand:DI 1 "register_operand" "0" )
  1057.                    ( match_operand:DI 2 "register_operand" "D" ))) 
  1058.   ]
  1059.   ""
  1060.   "*
  1061. {
  1062.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  1063.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  1064.     
  1065.     if ( op0_is_a )
  1066.     {
  1067.     if ( op2_is_a )
  1068.     {
  1069.         return \"clr    a\";
  1070.     }
  1071.     else
  1072.     {
  1073.         return \"jsr    lmod_ba\";
  1074.     }
  1075.     }
  1076.     else
  1077.     {
  1078.     if ( op2_is_a )
  1079.     {
  1080.         return \"jsr    lmod_ab\";
  1081.     }
  1082.     else
  1083.     {
  1084.         return \"clr    b\";
  1085.     }
  1086.     }
  1087. }" )    
  1088.  
  1089. ( define_insn "divdf3"
  1090.   [ ( set ( match_operand:DF 0 "general_operand" "=D" )
  1091.           ( div:DF ( match_operand:DF 1 "general_operand" "0" )
  1092.                    ( match_operand:DF 2 "general_operand" "D" ))) 
  1093.   ]
  1094.   ""
  1095.   "*
  1096. {
  1097.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  1098.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  1099.     
  1100.     if ( op0_is_a )
  1101.     {
  1102.     if ( op2_is_a )
  1103.     {
  1104.         return \"move    #>$400000,a\;move    #>$2000,a0\";
  1105.     }
  1106.     else
  1107.     {
  1108.         return \"jsr    fdiv_ba\";
  1109.     }
  1110.     }
  1111.     else
  1112.     {
  1113.     if ( op2_is_a )
  1114.     {
  1115.         return \"jsr    fdiv_ab\";
  1116.     }
  1117.     else
  1118.     {
  1119.         return \"move    #>$400000,b\;move    #>$2000,b0\";
  1120.     }
  1121.     }
  1122. }" )    
  1123.  
  1124. ( define_insn "divsf3"
  1125.   [ ( set ( match_operand:SF 0 "general_operand" "=D" )
  1126.           ( div:SF ( match_operand:SF 1 "general_operand" "0" )
  1127.                    ( match_operand:SF 2 "general_operand" "D" ))) 
  1128.   ]
  1129.   ""
  1130.   "*
  1131. {
  1132.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  1133.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  1134.     
  1135.     if ( op0_is_a )
  1136.     {
  1137.     if ( op2_is_a )
  1138.     {
  1139.         return \"move    #>$400000,a\;move    #>$2000,a0\";
  1140.     }
  1141.     else
  1142.     {
  1143.         return \"jsr    fdiv_ba\";
  1144.     }
  1145.     }
  1146.     else
  1147.     {
  1148.     if ( op2_is_a )
  1149.     {
  1150.         return \"jsr    fdiv_ab\";
  1151.     }
  1152.     else
  1153.     {
  1154.         return \"move    #>$400000,b\;move    #>$2000,b0\";
  1155.     }
  1156.     }
  1157. }" )    
  1158.  
  1159. ( define_insn "udivsi3"
  1160.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1161.       ( udiv:SI ( match_operand:SI 1 "register_operand" "0" )
  1162.             ( match_operand:SI 2 "register_operand" "D" )))
  1163.   ]
  1164.   ""
  1165.   "*
  1166. {
  1167.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  1168.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  1169.     
  1170.     if ( op0_is_a )
  1171.     {
  1172.     if ( op2_is_a )
  1173.     {
  1174.         return \"move    #>1,a\";
  1175.     }
  1176.     else
  1177.     {
  1178.         return \"jsr    udiv_ba\";
  1179.     }
  1180.     }
  1181.     else
  1182.     {
  1183.     if ( op2_is_a )
  1184.     {
  1185.         return \"jsr    udiv_ab\";
  1186.     }
  1187.     else
  1188.     {
  1189.         return \"move    #>1,b\";
  1190.     }
  1191.     }
  1192. }" )
  1193.  
  1194. ( define_insn "umodsi3"
  1195.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1196.       ( umod:SI ( match_operand:SI 1 "register_operand" "0" )
  1197.             ( match_operand:SI 2 "register_operand" "D" )))
  1198.   ]
  1199.   ""
  1200.   "*
  1201. {
  1202.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  1203.     int op2_is_a = ( DSP56_A_REGNUM == REGNO ( operands[2] ));
  1204.     
  1205.     if ( op0_is_a )
  1206.     {
  1207.     if ( op2_is_a )
  1208.     {
  1209.         return \"clr    a\";
  1210.     }
  1211.     else
  1212.     {
  1213.         return \"jsr    umod_ba\";
  1214.     }
  1215.     }
  1216.     else
  1217.     {
  1218.     if ( op2_is_a )
  1219.     {
  1220.         return \"jsr    umod_ab\";
  1221.     }
  1222.     else
  1223.     {
  1224.         return \"clr    b\";
  1225.     }
  1226.     }
  1227. }" )
  1228.  
  1229. ( define_expand "divsi3"
  1230.   [ ( set ( match_operand:SI 0 "register_operand" "" )
  1231.       ( div:SI ( match_operand:SI 1 "register_operand" "" )
  1232.            ( match_operand:SI 2 "register_operand" "" )))
  1233.   ]
  1234.   ""
  1235.   "
  1236. {
  1237.     emit_insn (
  1238.            gen_rtx ( PARALLEL, VOIDmode,
  1239.             gen_rtvec ( 3,
  1240.                    gen_rtx ( SET, VOIDmode, operands[0],
  1241.                         gen_rtx ( DIV, SImode, 
  1242.                              operands[1],
  1243.                              operands[2] )),
  1244.                    gen_rtx ( CLOBBER, VOIDmode, 
  1245.                         gen_reg_rtx ( SImode )),
  1246.                    gen_rtx ( CLOBBER, VOIDmode, 
  1247.                         gen_reg_rtx ( SImode )))));
  1248.     DONE;
  1249. }" )
  1250.  
  1251. ( define_insn ""
  1252.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1253.                ( div:SI ( match_operand:SI 1 "register_operand" "0" )
  1254.                 ( match_operand:SI 2 "register_operand" "S" )))
  1255.          ( clobber ( match_operand:SI 3 "register_operand" "=D" ))
  1256.          ( clobber ( match_operand:SI 4 "register_operand" "=S" )) ] )
  1257.   ]
  1258.   ""
  1259.   "*
  1260. {
  1261.     operands[5] = gen_label_rtx ( );
  1262.     
  1263.     if ( TARGET_REP ) 
  1264.     {
  1265.     return  \"tfr    %0,%3\;abs    %0\;clr    %0    %e0,%4\;move    %4,%h0\;asl    %0\;rep    #$18\;div    %2,%0\;eor    %2,%3\;jpl    %l5\;neg    %0\\n%l5\;move    %h0,%0\";
  1266.     }
  1267.     else
  1268.     {
  1269.     operands[6] = gen_label_rtx ( );
  1270.  
  1271.     return  \"tfr    %0,%3\;abs    %0\;clr    %0    %e0,%4\;move    %4,%h0\;asl    %0\;do    #$18,%l6\;div    %2,%0\\n%l6\;eor    %2,%3\;jpl    %l5\;neg    %0\\n%l5\;move    %h0,%0\";
  1272.     }
  1273. }" )
  1274.  
  1275. ( define_expand "modsi3"
  1276.   [ ( set ( match_operand:SI 0 "register_operand" "" )
  1277.       ( mod:SI ( match_operand:SI 1 "register_operand" "" )
  1278.            ( match_operand:SI 2 "register_operand" "" )))
  1279.   ]
  1280.   ""
  1281.   "
  1282. {
  1283.     emit_insn (
  1284.            gen_rtx ( PARALLEL, VOIDmode,
  1285.             gen_rtvec ( 3,
  1286.                    gen_rtx ( SET, VOIDmode, operands[0],
  1287.                         gen_rtx ( MOD, SImode, 
  1288.                              operands[1],
  1289.                              operands[2] )),
  1290.                    gen_rtx ( CLOBBER, VOIDmode, 
  1291.                         gen_reg_rtx ( SImode )),
  1292.                    gen_rtx ( CLOBBER, VOIDmode, 
  1293.                         gen_reg_rtx ( SImode )))));
  1294.     DONE;
  1295. }" )
  1296.  
  1297. ( define_insn ""
  1298.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1299.                ( mod:SI ( match_operand:SI 1 "register_operand" "0" )
  1300.                 ( match_operand:SI 2 "register_operand" "S" )))
  1301.          ( clobber ( match_operand:SI 3 "register_operand" "=D" ))
  1302.          ( clobber ( match_operand:SI 4 "register_operand" "=S" )) ] )
  1303.   ]
  1304.   ""
  1305.   "*
  1306. {
  1307.     operands[5] = gen_label_rtx ( );
  1308.     
  1309.     if ( TARGET_REP ) 
  1310.     {
  1311.      return  \"tfr    %0,%3\;abs    %0\;clr    %0    %e0,%4\;move    %4,%h0\;asl    %0\;rep    #$18\;div    %2,%0\;move    %e0,%4\;move    %2,%0\;abs    %0\;add    %4,%0\;asr    %0\;tst    %3\;jge    %l5\;neg    %0\\n%l5\";
  1312.     }
  1313.     else
  1314.     {
  1315.     operands[6] = gen_label_rtx ( );
  1316.  
  1317.     return  \"tfr    %0,%3\;abs    %0\;clr    %0    %e0,%4\;move    %4,%h0\;asl    %0\;do    #$18,%l6\;div    %2,%0\\n%l6\;move    %e0,%4\;move    %2,%0\;abs    %0\;add    %4,%0\;asr    %0\;tst    %3\;jge    %l5\;neg    %0\\n%l5\";
  1318.     }
  1319. }" )
  1320.  
  1321. ;;
  1322. ;;  ...........................................................................
  1323. ;;
  1324. ;;          NEGATIONS
  1325. ;;
  1326. ;;  ...........................................................................
  1327. ;;
  1328.  
  1329. ;; We provide quick software emulation via a subroutine that emulates
  1330. ;; a floating point instruction.
  1331.  
  1332. ( define_insn "negdf2"
  1333.   [ ( set ( match_operand:DF 0 "general_operand" "=D" )
  1334.           ( neg:DF ( match_operand:DF 1 "general_operand" "0" )))
  1335.   ]
  1336.   ""
  1337.   "*
  1338. {
  1339.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  1340.     {
  1341.     return \"jsr    fneg_a\";
  1342.     }
  1343.     else
  1344.     {
  1345.     return \"jsr    fneg_b\";
  1346.     }
  1347. }" )    
  1348.  
  1349. ( define_insn "negsf2"
  1350.   [ ( set ( match_operand:SF 0 "general_operand" "=D" )
  1351.           ( neg:SF ( match_operand:SF 1 "general_operand" "0" )))
  1352.   ]
  1353.   ""
  1354.   "*
  1355. {
  1356.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  1357.     {
  1358.     return \"jsr    fneg_a\";
  1359.     }
  1360.     else
  1361.     {
  1362.     return \"jsr    fneg_b\";
  1363.     }
  1364. }" )    
  1365.  
  1366. ( define_insn "negsi2"
  1367.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1368.       ( neg:SI ( match_operand:SI 1 "register_operand" "0" )))
  1369.   ]
  1370.   ""
  1371.   "neg    %0" )
  1372.  
  1373. ( define_insn "negdi2"
  1374.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1375.       ( neg:DI ( match_operand:DI 1 "register_operand" "0" )))
  1376.   ]
  1377.   ""
  1378.   "neg    %0" )
  1379.  
  1380. ;;
  1381. ;;  ...........................................................................
  1382. ;;
  1383. ;;          ABSOLUTE VALUES
  1384. ;;
  1385. ;;  ...........................................................................
  1386. ;;
  1387.  
  1388. ( define_insn "abssi2"
  1389.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1390.       ( abs:SI ( match_operand:SI 1 "register_operand" "0" ) ) ) ]
  1391.   ""
  1392.   "abs    %0" )
  1393.  
  1394. ( define_insn "absdi2"
  1395.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1396.       ( abs:DI ( match_operand:DI 1 "register_operand" "0" ) ) ) ]
  1397.   ""
  1398.   "abs    %0" )
  1399.  
  1400. ;;
  1401. ;;  ...........................................................................
  1402. ;;
  1403. ;;          LOGICAL AND
  1404. ;;
  1405. ;;  ...........................................................................
  1406. ;;
  1407.  
  1408. ( define_insn "andsi3"
  1409.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1410.       ( and:SI ( match_operand:SI 1 "register_operand" "0" )
  1411.            ( match_operand:SI 2 "register_operand" "S" ) ) ) ]
  1412.   ""
  1413.   "and    %2,%0\;move    %e0,%0" )
  1414.  
  1415. ( define_insn "anddi3"
  1416.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1417.       ( and:DI ( match_operand:DI 1 "register_operand" "0" )
  1418.            ( match_operand:DI 2 "register_operand" "S" ) ) ) ]
  1419.   ""
  1420.   "*
  1421. {
  1422.     RETURN_DSP ( \"and    %g2,%0    %h0,@:(r6)\;move    %e0,%h0\;move    @:(r6),%e0\;and    %2,%0\;move    %e0,@:(r6)\;move    %h0,%0\;move    @:(r6),%h0\" );
  1423. }" )
  1424.  
  1425. ;;
  1426. ;;  ...........................................................................
  1427. ;;
  1428. ;;          LOGICAL INCLUSIVE OR
  1429. ;;
  1430. ;;  ...........................................................................
  1431. ;;
  1432.  
  1433. ( define_insn "iorsi3"
  1434.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1435.       ( ior:SI ( match_operand:SI 1 "register_operand" "0" )
  1436.            ( match_operand:SI 2 "register_operand" "S" ) ) ) ]
  1437.   ""
  1438.   "or    %2,%0\;move    %e0,%0" )
  1439.  
  1440. ( define_insn "iordi3"
  1441.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1442.       ( ior:DI ( match_operand:DI 1 "register_operand" "0" )
  1443.            ( match_operand:DI 2 "register_operand" "S" ) ) ) ]
  1444.   ""
  1445.   "*
  1446. {
  1447.     RETURN_DSP ( \"or    %g2,%0    %h0,@:(r6)\;move    %e0,%h0\;move    @:(r6),%e0\;or    %2,%0\;move    %e0,@:(r6)\;move    %h0,%0\;move    @:(r6),%h0\" );
  1448. }" )
  1449.  
  1450. ;;
  1451. ;;  ...........................................................................
  1452. ;;
  1453. ;;          LOGICAL EXCLUSIVE OR
  1454. ;;
  1455. ;;  ...........................................................................
  1456. ;;
  1457.  
  1458. ( define_insn "xorsi3"
  1459.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1460.       ( xor:SI ( match_operand:SI 1 "register_operand" "0" )
  1461.            ( match_operand:SI 2 "register_operand" "S" ) ) ) ]
  1462.   ""
  1463.   "eor    %2,%0\;move    %e0,%0" )
  1464.  
  1465. ( define_insn "xordi3"
  1466.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1467.       ( xor:DI ( match_operand:DI 1 "register_operand" "0" )
  1468.            ( match_operand:DI 2 "register_operand" "S" ) ) ) ]
  1469.   ""
  1470.   "*
  1471. {
  1472.     RETURN_DSP ( \"eor    %g2,%0    %h0,@:(r6)\;move    %e0,%h0\;move    @:(r6),%e0\;eor    %2,%0\;move    %e0,@:(r6)\;move    %h0,%0\;move    @:(r6),%h0\" );
  1473. }" )
  1474.  
  1475. ;;
  1476. ;;  ...........................................................................
  1477. ;;
  1478. ;;          ONE'S COMPLEMENT
  1479. ;;
  1480. ;;  ...........................................................................
  1481. ;;
  1482.  
  1483. ( define_insn "one_cmplsi2"
  1484.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1485.       ( not:SI ( match_operand:SI 1 "register_operand" "0" ))) 
  1486.   ]
  1487.   ""
  1488.   "not    %0\;move    %e0,%0" )
  1489.  
  1490. ( define_insn "one_cmpldi2"
  1491.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1492.       ( not:DI ( match_operand:DI 1 "register_operand" "0" )))
  1493.   ]
  1494.   ""
  1495.   "*
  1496. {
  1497.     RETURN_DSP ( \"not    %0    %h0,@:(r6)\;move    %e0,%h0\;move    @:(r6),%e0\;not    %0\;move    %e0,@:(r6)\;move    %h0,%0\;move    @:(r6),%h0\" );
  1498. }" )
  1499.  
  1500. ;;
  1501. ;;  ...........................................................................
  1502. ;;
  1503. ;;          ARITHMETIC SHIFTS
  1504. ;;
  1505. ;;  ...........................................................................
  1506. ;;
  1507.  
  1508. ;; note that we preceed each shift insn by an unnamed insn. the unnamed insn
  1509. ;; is used to catch shifts with constant shift counts before said constants
  1510. ;; are promoted to registers. 
  1511.  
  1512. ( define_insn ""
  1513.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1514.       ( ashift:SI ( match_operand:SI 1 "register_operand" "0" )
  1515.               ( match_operand:SI 2 "immediate_operand" "i" )))
  1516.   ]
  1517.   ""
  1518.   "*
  1519. {
  1520.     if ( 1 == INTVAL ( operands[2] ))
  1521.     {
  1522.     return \"asl    %0\;move    %e0,%0\";
  1523.     }
  1524.     else if ( 2 == INTVAL ( operands[2] ))
  1525.     {
  1526.     return \"asl    %0\;asl    %0\;move    %e0,%0\";
  1527.     }
  1528.     else
  1529.     {
  1530.     operands[3] = copy_rtx ( operands[2] );
  1531.     INTVAL ( operands[3] ) &= 0xfff;
  1532.         
  1533.     if ( TARGET_REP )
  1534.     {
  1535.         return \"rep    #%c3\;asl    %0\;move    %e0,%0\";
  1536.     }
  1537.     else
  1538.     {
  1539.         operands[4] = gen_label_rtx ( );
  1540.         
  1541.         return \"do    #%c3,%l4\;asl    %0\\n%l4\;move    %e0,%0\";
  1542.     }
  1543.     }
  1544. }" )
  1545.  
  1546. ( define_insn "ashlsi3"
  1547.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1548.       ( ashift:SI ( match_operand:SI 1 "register_operand" "0" )
  1549.               ( match_operand:SI 2 "general_operand" "D" )))
  1550.   ]
  1551.   ""
  1552.   "*
  1553. {
  1554.     operands[3] = gen_label_rtx ( );
  1555.     
  1556.     if ( TARGET_REP )
  1557.     {
  1558.     return \"tst    %2\;jeq    %l3\;rep    %2\;asl    %0\;move    %e0,%0\\n%l3\";
  1559.     }
  1560.     else
  1561.     {
  1562.     operands[4] = gen_label_rtx ( );
  1563.     
  1564.     return \"tst    %2\;jeq    %l3\;do    %2,%l4\;asl    %0\\n%l4\;move    %e0,%0\\n%l3\";
  1565.     }
  1566. }")
  1567.  
  1568. ( define_insn ""
  1569.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1570.       ( ashiftrt:SI ( match_operand:SI 1 "register_operand" "0" )
  1571.             ( match_operand:SI 2 "immediate_operand" "i" )))
  1572.   ]
  1573.   ""
  1574.   "*
  1575. {
  1576.     if ( 1 == INTVAL ( operands[2] ))
  1577.     {
  1578.     return \"move    %e0,%0\;asr    %0\;move    %e0,%0\";
  1579.     }
  1580.     else if ( 2 == INTVAL ( operands[2] ))
  1581.     {
  1582.     return \"move    %e0,%0\;asr    %0\;asr    %0\;move    %e0,%0\";
  1583.     }
  1584.     else
  1585.     {
  1586.     operands[3] = copy_rtx ( operands[2] );
  1587.     INTVAL ( operands[3] ) &= 0xfff;
  1588.     
  1589.     if ( TARGET_REP )
  1590.     {
  1591.         return \"move    %e0,%0\;rep    #%c3\;asr    %0\;move    %e0,%0\";
  1592.     }
  1593.     else
  1594.     {
  1595.         operands[4] = gen_label_rtx ( );
  1596.         
  1597.         return \"move    %e0,%0\;do    #%c3,%l4\;asr    %0\\n%l4\;move    %e0,%0\";
  1598.     }
  1599.     }
  1600. }" )
  1601.  
  1602. ( define_insn "ashrsi3"
  1603.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1604.      ( ashiftrt:SI ( match_operand:SI 1 "register_operand" "0" )
  1605.                    ( match_operand:SI 2 "general_operand" "D" )))
  1606.   ]
  1607.   ""
  1608.   "*
  1609. {
  1610.     operands[3] = gen_label_rtx ( );
  1611.     
  1612.     if ( TARGET_REP )
  1613.     {
  1614.     return \"tst    %2\;jeq    %l3\;move    %e0,%0\;rep    %2\;asr    %0\;move    %e0,%0\\n%l3\";
  1615.     }
  1616.     else
  1617.     {
  1618.     operands[4] = gen_label_rtx ( );
  1619.     
  1620.     return \"tst    %2\;jeq    %l3\;move    %e0,%0\;do    %2,%l4\;asr    %0\\n%l4\;move    %e0,%0\\n%l3\";
  1621.     }
  1622. }")
  1623.  
  1624. ( define_insn ""
  1625.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1626.      ( ashift:DI ( match_operand:DI 1 "register_operand" "0" )
  1627.                  ( match_operand:SI 2 "immediate_operand" "i" )))
  1628.   ]
  1629.   ""
  1630.   "*
  1631. {
  1632.     if ( 1 == INTVAL ( operands[2] ))
  1633.     {
  1634.     return \"asl    %0\";
  1635.     }
  1636.     else if ( 2 == INTVAL ( operands[2] ))
  1637.     {
  1638.     return \"asl    %0\;asl    %0\";
  1639.     }
  1640.     else
  1641.     {
  1642.     operands[3] = copy_rtx ( operands[2] );
  1643.     INTVAL ( operands[3] ) &= 0xfff;
  1644.     
  1645.     if ( TARGET_REP )
  1646.     {
  1647.         return \"rep    #%c3\;asl    %0\";
  1648.     }
  1649.     else
  1650.     {
  1651.         operands[4] = gen_label_rtx ( );
  1652.         
  1653.         return \"do    #%c3,%l4\;asl    %0\\n%l4\";
  1654.     }
  1655.     }
  1656. }" )
  1657.  
  1658. ( define_insn "ashldi3"
  1659.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1660.      ( ashift:DI ( match_operand:DI 1 "register_operand" "0" )
  1661.                  ( match_operand:SI 2 "general_operand" "D" )))
  1662.   ]
  1663.   ""
  1664.   "*
  1665. {
  1666.     operands[3] = gen_label_rtx ( );
  1667.     
  1668.     if ( TARGET_REP )
  1669.     {
  1670.     return \"tst    %d2\;jeq    %l3\;rep    %2\;asl    %0\\n%l3\";
  1671.     }
  1672.     else
  1673.     {
  1674.     return \"tst    %d2\;jeq    %l3\;do    %2,%l3\;asl    %0\\n%l3\";
  1675.     }
  1676. }")
  1677.  
  1678. ( define_insn ""
  1679.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1680.      ( ashiftrt:DI ( match_operand:DI 1 "register_operand" "0" )
  1681.                    ( match_operand:SI 2 "immediate_operand" "i" )))
  1682.   ]
  1683.   ""
  1684.   "*
  1685. {
  1686.     if ( 1 == INTVAL ( operands[2] ))
  1687.     {
  1688.     RETURN_DSP ( \"move    %h0,@:(r6)\;move    %e0,%0\;move    @:(r6),%h0\;asr    %0\" );
  1689.     }
  1690.     else if ( 2 == INTVAL ( operands[2] ))
  1691.     {
  1692.     RETURN_DSP ( \"move    %h0,@:(r6)\;move    %e0,%0\;move    @:(r6),%h0\;asr    %0\;asr    %0\" );
  1693.     }
  1694.     else
  1695.     {
  1696.     operands[3] = copy_rtx ( operands[2] );
  1697.     INTVAL ( operands[3] ) &= 0xfff;
  1698.     
  1699.     if ( TARGET_REP )
  1700.     {
  1701.         RETURN_DSP ( \"move    %h0,@:(r6)\;move    %e0,%0\;move    @:(r6),%h0\;rep    #%c3\;asr    %0\" );
  1702.     }
  1703.     else
  1704.     {
  1705.         operands[4] = gen_label_rtx ( );
  1706.         
  1707.         RETURN_DSP ( \"move    %h0,@:(r6)\;move    %e0,%0\;move    @:(r6),%h0\;do    #%c3,%l4\;asr    %0\\n%l4\" );
  1708.     }
  1709.     }
  1710. }" )
  1711.  
  1712. ( define_insn "ashrdi3"
  1713.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1714.      ( ashiftrt:DI ( match_operand:DI 1 "register_operand" "0" )
  1715.                    ( match_operand:SI 2 "general_operand" "D" )))
  1716.   ]
  1717.   ""
  1718.   "*
  1719. {
  1720.     operands[3] = gen_label_rtx ( );
  1721.  
  1722.     if ( TARGET_REP )
  1723.     {
  1724.     RETURN_DSP ( \"move    %h0,@:(r6)\;move    %e0,%0\;move    @:(r6),%h0\;tst    %d2\;jeq    %l3\;rep    %2\;asr    %0\\n%l3\" );
  1725.     }
  1726.     else
  1727.     {
  1728.     RETURN_DSP ( \"move    %h0,@:(r6)\;move    %e0,%0\;move    @:(r6),%h0\;tst    %d2\;jeq    %l3\;do    %2,%l3\;asr    %0\\n%l3\" );
  1729.     }
  1730. }")
  1731.  
  1732. ;;
  1733. ;;  ...........................................................................
  1734. ;;
  1735. ;;          LOGICAL SHIFTS
  1736. ;;
  1737. ;;  ...........................................................................
  1738. ;;
  1739.  
  1740. ;; note that we preceed each shift insn by an unnamed insn. the unnamed insn
  1741. ;; is used to catch shifts with constant shift counts before said constants
  1742. ;; are promoted to registers. 
  1743.  
  1744. ( define_insn ""
  1745.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1746.      ( lshift:SI ( match_operand:SI 1 "register_operand" "0" )
  1747.                  ( match_operand:SI 2 "immediate_operand" "i" )))
  1748.   ]
  1749.   ""
  1750.   "*
  1751. {
  1752.     if ( 1 == INTVAL ( operands[2] ))
  1753.     {
  1754.     return \"lsl    %0\";
  1755.     }
  1756.     else if ( 2 == INTVAL ( operands[2] ))
  1757.     {
  1758.     return \"lsl    %0\;lsl    %0\";
  1759.     }
  1760.     else
  1761.     {
  1762.     operands[3] = copy_rtx ( operands[2] );
  1763.     INTVAL ( operands[3] ) &= 0xfff;
  1764.     
  1765.     if ( TARGET_REP )
  1766.     {
  1767.         return \"rep    #%c3\;lsl    %0\";
  1768.     }
  1769.     else
  1770.     {
  1771.         operands[4] = gen_label_rtx ( );
  1772.         
  1773.         return \"do    #%c3,%l4\;lsl    %0\\n%l4\";
  1774.     }
  1775.     }
  1776. }" )
  1777.  
  1778. ( define_insn "lshlsi3"
  1779.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1780.      ( lshift:SI ( match_operand:SI 1 "register_operand" "0" )
  1781.                  ( match_operand:SI 2 "general_operand" "D" )))
  1782.   ]
  1783.   ""
  1784.   "*
  1785. {
  1786.     operands[3] = gen_label_rtx ( );
  1787.     
  1788.     if ( TARGET_REP )
  1789.     {
  1790.     return \"tst    %2\;jeq    %l3\;rep    %2\;lsl    %0\\n%l3\";
  1791.     }
  1792.     else
  1793.     {
  1794.     return \"tst    %2\;jeq    %l3\;do    %2,%l3\;lsl    %0\\n%l3\";
  1795.     }
  1796. }")
  1797.  
  1798. ( define_insn ""
  1799.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1800.      ( lshiftrt:SI ( match_operand:SI 1 "register_operand" "0" )
  1801.                    ( match_operand:SI 2 "immediate_operand" "i" )))
  1802.   ]
  1803.   ""
  1804.   "*
  1805. {
  1806.     if ( 1 == INTVAL ( operands[2] ))
  1807.     {
  1808.     return \"lsr    %0\";
  1809.     }
  1810.     else if ( 2 == INTVAL ( operands[2] ))
  1811.     {
  1812.     return \"lsr    %0\;lsr    %0\";
  1813.     }
  1814.     else
  1815.     {
  1816.     operands[3] = copy_rtx ( operands[2] );
  1817.     INTVAL ( operands[3] ) &= 0xfff;
  1818.     
  1819.     if ( TARGET_REP )
  1820.     {
  1821.         return \"rep    #%c3\;lsr    %0\";
  1822.     }
  1823.     else
  1824.     {
  1825.         operands[4] = gen_label_rtx ( );
  1826.         
  1827.         return \"do    #%c3,%l4\;lsr    %0\\n%l4\";
  1828.     }
  1829.     }
  1830. }" )
  1831.  
  1832. ( define_insn "lshrsi3"
  1833.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1834.      ( lshiftrt:SI ( match_operand:SI 1 "register_operand" "0" )
  1835.                    ( match_operand:SI 2 "general_operand" "D" )))
  1836.   ]
  1837.   ""
  1838.   "*
  1839. {
  1840.     operands[3] = gen_label_rtx ( );
  1841.     
  1842.     if ( TARGET_REP )
  1843.     {
  1844.     return \"tst    %2\;jeq    %l3\;rep    %2\;lsr    %0\\n%l3\";
  1845.     }
  1846.     else
  1847.     {
  1848.     return \"tst    %2\;jeq    %l3\;do    %2,%l3\;lsr    %0\\n%l3\";
  1849.     }
  1850. }")
  1851.  
  1852. ( define_insn ""
  1853.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1854.      ( lshift:DI ( match_operand:DI 1 "register_operand" "0" )
  1855.                  ( match_operand:SI 2 "immediate_operand" "i" )))
  1856.   ]
  1857.   ""
  1858.   "*
  1859. {
  1860.     if ( 1 == INTVAL ( operands[2] ))
  1861.     {
  1862.     return \"asl    %0\";
  1863.     }
  1864.     else if ( 2 == INTVAL ( operands[2] ))
  1865.     {
  1866.     return \"asl    %0\;asl    %0\";
  1867.     }
  1868.     else
  1869.     {
  1870.     operands[3] = copy_rtx ( operands[2] );
  1871.     INTVAL ( operands[3] ) &= 0xfff;
  1872.     
  1873.     if ( TARGET_REP )
  1874.     {
  1875.         return \"rep    #%c3\;asl    %0\";
  1876.     }
  1877.     else
  1878.     {    
  1879.         operands[4] = gen_label_rtx ( );
  1880.         
  1881.         return \"do    #%c3,%l4\;asl    %0\\n%l4\";
  1882.     }
  1883.     }
  1884. }" )
  1885.  
  1886. ( define_insn "lshldi3"
  1887.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1888.      ( lshift:DI ( match_operand:DI 1 "register_operand" "0" )
  1889.                  ( match_operand:SI 2 "general_operand" "D" )))
  1890.   ]
  1891.   ""
  1892.   "*
  1893. {
  1894.     operands[3] = gen_label_rtx ( );
  1895.  
  1896.     if ( TARGET_REP )
  1897.     {
  1898.     return \"tst    %d2\;jeq    %l3\;rep    %2\;asl    %0\\n%l3\";
  1899.     }
  1900.     else
  1901.     {
  1902.     return \"tst    %d2\;jeq    %l3\;do    %2,%l3\;asl    %0\\n%l3\";
  1903.     }
  1904. }")
  1905.  
  1906. ( define_insn ""
  1907.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1908.      ( lshiftrt:DI ( match_operand:DI 1 "register_operand" "0" )
  1909.                    ( match_operand:SI 2 "immediate_operand" "i" )))
  1910.   ]
  1911.   ""
  1912.   "*
  1913. {
  1914.     if ( 1 == INTVAL ( operands[2] ))
  1915.     {
  1916.     return \"move    #0,%k0\;asr    %0\";
  1917.     }
  1918.     else if ( 2 == INTVAL ( operands[2] ))
  1919.     {
  1920.     return \"move    #0,%k0\;asr    %0\;asr    %0\";
  1921.     }
  1922.     else
  1923.     {
  1924.     operands[3] = copy_rtx ( operands[2] );
  1925.     INTVAL ( operands[3] ) &= 0xfff;
  1926.     
  1927.     if ( TARGET_REP )
  1928.     {
  1929.         return \"move    #0,%k0\;rep    #%c3\;asr    %0\";
  1930.     }
  1931.     else
  1932.     {
  1933.         operands[4] = gen_label_rtx ( );
  1934.         
  1935.         return \"move    #0,%k0\;do    #%c3,%l4\;asr    %0\\n%l4\";
  1936.     }
  1937.     }
  1938. }" )
  1939.  
  1940. ( define_insn "lshrdi3"
  1941.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  1942.      ( lshiftrt:DI ( match_operand:DI 1 "register_operand" "0" )
  1943.                    ( match_operand:SI 2 "general_operand" "D" )))
  1944.   ]
  1945.   ""
  1946.   "*
  1947. {
  1948.     operands[3] = gen_label_rtx ( );
  1949.     
  1950.     if ( TARGET_REP )
  1951.     {
  1952.     return \"tst    %d2\;jeq    %l3\;move    #0,%k0\;rep    %2\;asr    %0\\n%l3\";
  1953.     }
  1954.     else
  1955.     {
  1956.     return \"tst    %d2\;jeq    %l3\;move    #0,%k0\;do    %2,%l3\;asr    %0\\n%l3\";
  1957.     }
  1958. }")
  1959.  
  1960. ;;
  1961. ;;  ...........................................................................
  1962. ;;
  1963. ;;          ROTATIONS
  1964. ;;
  1965. ;;  ...........................................................................
  1966. ;;
  1967.  
  1968. ;; note that we preceed each shift insn by an unnamed insn. the unnamed insn
  1969. ;; is used to catch shifts with constant shift counts before said constants
  1970. ;; are promoted to registers. 
  1971.  
  1972. ( define_insn ""
  1973.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  1974.      ( rotate:SI ( match_operand:SI 1 "register_operand" "0" )
  1975.                  ( match_operand:SI 2 "immediate_operand" "i" )))
  1976.   ]
  1977.   ""
  1978.   "*
  1979. {
  1980.     if ( 1 == INTVAL ( operands[2] ))
  1981.     {
  1982.     return \"rol    %0\";
  1983.     }
  1984.     else if ( 2 == INTVAL ( operands[2] ))
  1985.     {
  1986.     return \"rol    %0\;rol    %0\";
  1987.     }
  1988.     else
  1989.     {
  1990.     operands[3] = copy_rtx ( operands[2] );
  1991.     INTVAL ( operands[3] ) &= 0xfff;
  1992.     
  1993.     if ( TARGET_REP )
  1994.     {
  1995.         return \"rep    #%c3\;rol    %0\";
  1996.     }
  1997.     else
  1998.     {
  1999.         operands[4] = gen_label_rtx ( );
  2000.         
  2001.         return \"do    #%c3,%l4\;rol    %0\\n%l4\";
  2002.     }
  2003.     }
  2004. }" )
  2005.  
  2006. ( define_insn "rotlsi3"
  2007.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  2008.      ( rotate:SI ( match_operand:SI 1 "register_operand" "0" )
  2009.                  ( match_operand:SI 2 "general_operand" "D" )))
  2010.   ]
  2011.   ""
  2012.   "*
  2013. {
  2014.     operands[3] = gen_label_rtx ( );
  2015.     
  2016.     if ( TARGET_REP )
  2017.     {
  2018.     return \"tst    %2\;jeq    %l3\;rep    %2\;rol    %0\\n%l3\";
  2019.     }
  2020.     else
  2021.     {
  2022.     return \"tst    %2\;jeq    %l3\;do    %2,%l3\;rol    %0\\n%l3\";
  2023.     }
  2024. }")
  2025.  
  2026. ( define_insn ""
  2027.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  2028.      ( rotatert:SI ( match_operand:SI 1 "register_operand" "0" )
  2029.                    ( match_operand:SI 2 "immediate_operand" "i" )))
  2030.   ]
  2031.   ""
  2032.   "*
  2033. {
  2034.     if ( 1 == INTVAL ( operands[2] ))
  2035.     {
  2036.     return \"ror    %0\";
  2037.     }
  2038.     else if ( 2 == INTVAL ( operands[2] ))
  2039.     {
  2040.     return \"ror    %0\;ror    %0\";
  2041.     }
  2042.     else
  2043.     {
  2044.     operands[3] = copy_rtx ( operands[2] );
  2045.     INTVAL ( operands[3] ) &= 0xfff;
  2046.     
  2047.     if ( TARGET_REP )
  2048.     {
  2049.         return \"rep    #%c3\;ror    %0\";
  2050.     }
  2051.     else
  2052.     {
  2053.         operands[4] = gen_label_rtx ( );
  2054.         
  2055.         return \"do    #%c3,%l4\;ror    %0\\n%l4\";
  2056.     }
  2057.     }
  2058. }" )
  2059.  
  2060. ( define_insn "rotrsi3"
  2061.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  2062.      ( rotatert:SI ( match_operand:SI 1 "register_operand" "0" )
  2063.                    ( match_operand:SI 2 "general_operand" "D" )))
  2064.   ]
  2065.   ""
  2066.   "*
  2067. {
  2068.     operands[3] = gen_label_rtx ( );
  2069.     
  2070.     if ( TARGET_REP )
  2071.     {
  2072.     return \"tst    %2\;jeq    %l3\;rep    %2\;ror    %0\\n%l3\";
  2073.     }
  2074.     else
  2075.     {
  2076.     return \"tst    %2\;jeq    %l3\;do    %2,%l3\;ror    %0\\n%l3\";
  2077.     }
  2078. }")
  2079.  
  2080. ;;
  2081. ;;  ...........................................................................
  2082. ;;
  2083. ;;          COMPARISONS
  2084. ;;
  2085. ;;  ...........................................................................
  2086. ;;
  2087.  
  2088. ;; We provide quick software emulation via a subroutine that emulates
  2089. ;; a floating point instruction.
  2090.  
  2091. ( define_insn "cmpdf"
  2092.   [ ( set ( cc0 )
  2093.           ( compare ( match_operand:DF 0 "register_operand" "D" )
  2094.                     ( match_operand:DF 1 "register_operand" "D" )))
  2095.   ]
  2096.   ""
  2097.   "*
  2098. {
  2099.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  2100.     int op1_is_a = ( DSP56_A_REGNUM == REGNO ( operands[1] ));
  2101.     
  2102.     if ( op0_is_a )
  2103.     {
  2104.     if ( op1_is_a )
  2105.     {
  2106.         return \"andi    #$00,ccr\;ori    #$14,ccr\";
  2107.     }
  2108.     else
  2109.     {
  2110.         return \"jsr    fcmp_ba\";
  2111.     }
  2112.     }
  2113.     else
  2114.     {
  2115.     if ( op1_is_a )
  2116.     {
  2117.         return \"jsr    fcmp_ab\";
  2118.     }
  2119.     else
  2120.     {
  2121.         return \"andi    #$00,ccr\;ori    #$14,ccr\";
  2122.     }
  2123.     }
  2124. }" )    
  2125.  
  2126. ( define_insn "cmpsf"
  2127.   [ ( set ( cc0 )
  2128.           ( compare ( match_operand:SF 0 "register_operand" "D" )
  2129.                     ( match_operand:SF 1 "register_operand" "D" )))
  2130.   ]
  2131.   ""
  2132.   "*
  2133. {
  2134.     int op0_is_a = ( DSP56_A_REGNUM == REGNO ( operands[0] ));
  2135.     int op1_is_a = ( DSP56_A_REGNUM == REGNO ( operands[1] ));
  2136.     
  2137.     if ( op0_is_a )
  2138.     {
  2139.     if ( op1_is_a )
  2140.     {
  2141.         return \"andi    #$00,ccr\;ori    #$14,ccr\";
  2142.     }
  2143.     else
  2144.     {
  2145.         return \"jsr    fcmp_ba\";
  2146.     }
  2147.     }
  2148.     else
  2149.     {
  2150.     if ( op1_is_a )
  2151.     {
  2152.         return \"jsr    fcmp_ab\";
  2153.     }
  2154.     else
  2155.     {
  2156.         return \"andi    #$00,ccr\;ori    #$14,ccr\";
  2157.     }
  2158.     }
  2159. }" )    
  2160.  
  2161. ( define_expand "cmppsi"
  2162.   [ ( set ( cc0 )
  2163.       ( compare ( match_operand:PSI 0 "register_operand" "" )
  2164.             ( match_operand:PSI 1 "register_operand" "" ))) ]
  2165.   ""
  2166.   "
  2167. {
  2168.     emit_insn 
  2169.     ( gen_rtx 
  2170.      ( PARALLEL, VOIDmode, gen_rtvec
  2171.       ( 3, 
  2172.        gen_rtx ( SET, VOIDmode, cc0_rtx, 
  2173.             gen_rtx ( COMPARE, PSImode, operands[0], operands[1] )),
  2174.        gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( PSImode )),
  2175.        gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( PSImode )))));
  2176.     DONE;
  2177. }" )
  2178.  
  2179. ( define_insn ""
  2180.   [ ( parallel
  2181.       [ ( set ( cc0 )
  2182.           ( compare ( match_operand:PSI 0 "register_operand" "A" )
  2183.             ( match_operand:PSI 1 "register_operand" "A" )))
  2184.     ( clobber ( match_operand:PSI 2 "register_operand" "=D" ))
  2185.     ( clobber ( match_operand:PSI 3 "register_operand" "=*S*D" )) ] )]
  2186.   ""
  2187.   "*
  2188. {
  2189.     extern rtx next_cc_relevancy ( );
  2190.     rtx relevant_insn, relevant_body;
  2191.     
  2192.     /* sometimes this compiler manages attempt ( compare ( reg x ) ( reg x )).
  2193.        the condition codes implied by this are obvious. we peek down the insn
  2194.        chain and discover the next_cc0_relevancy ( ). if we discover
  2195.        that the ccs are being set gratuitiously, we ignore this compare, 
  2196.        otherwise we change the cc0 consumer to be a constant load in the case
  2197.        of an Scond or a hard branch or nop in the case of a Bcond. */
  2198.  
  2199.     if ( REGNO ( operands[0] ) == REGNO ( operands[1] ))
  2200.     {
  2201.     relevant_insn = next_cc_relevancy ( insn );
  2202.     relevant_body = PATTERN ( relevant_insn );
  2203.     
  2204.     if ( JUMP_INSN == GET_CODE ( relevant_insn ))
  2205.     {
  2206.         if (( IF_THEN_ELSE == GET_CODE ( relevant_body =
  2207.                         XEXP ( relevant_body, 1 ))) &&
  2208.         ( CONST_INT != 
  2209.          GET_CODE ( XEXP ( relevant_body, 0 ))))
  2210.         {
  2211.         if (( GEU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2212.             ( GE == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2213.             ( LEU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2214.             ( LE == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2215.             ( EQU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2216.             ( EQ == GET_CODE ( XEXP ( relevant_body, 0 ))))
  2217.         {
  2218.             /* change ineq into const1_rtx because x == x always. */
  2219.  
  2220.             if ( pc_rtx == XEXP ( XEXP ( PATTERN ( relevant_insn ),
  2221.                         1 ), 1 ))
  2222.             {
  2223.             delete_insn ( relevant_insn );
  2224.             }
  2225.             else
  2226.             {
  2227.             INSN_CODE ( relevant_insn ) = -1;
  2228.  
  2229.             XEXP ( PATTERN ( relevant_insn ), 1 ) =
  2230.                 XEXP ( XEXP ( PATTERN ( relevant_insn ), 1 ), 1 );
  2231.             }
  2232.         }
  2233.         else
  2234.         {
  2235.             /* otherwise change ineq into const0_rtx. */
  2236.             
  2237.             if ( pc_rtx == XEXP ( XEXP ( PATTERN ( relevant_insn ),
  2238.                         1 ), 1 ))
  2239.             {
  2240.             INSN_CODE ( relevant_insn ) = -1;
  2241.  
  2242.             XEXP ( PATTERN ( relevant_insn ), 1 ) =
  2243.                 XEXP ( XEXP ( PATTERN ( relevant_insn ), 1 ), 2 );
  2244.             }
  2245.             else
  2246.             {
  2247.             delete_insn ( relevant_insn );
  2248.             }
  2249.         }
  2250.         }
  2251.     }
  2252.     else if (( INSN == GET_CODE ( relevant_insn )) &&
  2253.          ( PARALLEL == GET_CODE ( relevant_body )) &&
  2254.          ( SET == GET_CODE ( relevant_body = 
  2255.                     XVECEXP ( relevant_body, 0, 0 ))) &&
  2256.          ( 0 == strcmp ( \"ee\",
  2257.                 GET_RTX_FORMAT ( GET_CODE ( XEXP ( relevant_body, 1 ))))) &&
  2258.          ( cc0_rtx == XEXP ( XEXP ( relevant_body, 1 ), 0 )))
  2259.     {
  2260.         if (( GEU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2261.         ( GE == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2262.         ( LEU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2263.         ( LE == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2264.         ( EQU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2265.         ( EQ == GET_CODE ( XEXP ( relevant_body, 1 ))))
  2266.         {
  2267.         /* change ineq into const1_rtx because x == x always. */
  2268.  
  2269.         XEXP ( relevant_body, 1 ) = const1_rtx;
  2270.         }
  2271.         else 
  2272.         {
  2273.         /* otherwise change ineq into const0_rtx. */
  2274.  
  2275.         XEXP ( relevant_body, 1 ) = const0_rtx;
  2276.         }
  2277.         INSN_CODE ( relevant_insn ) = -1;
  2278.     }
  2279.     return \"\";
  2280.     }
  2281.     cc_status.mdep = CC_UNKNOWN;
  2282.     return \"move    %0,%2\;move    %1,%3\;cmp    %3,%2\";
  2283. }" )
  2284.  
  2285. ( define_insn ""
  2286.   [ ( set ( cc0 )
  2287.           ( compare ( match_operand:SI 0 "register_operand" "D" )
  2288.                     ( match_operand:SI 1 "register_operand" "D" )))
  2289.   ]
  2290.   "UNSIGNED_COMPARE_P ( insn )"
  2291.   "*
  2292. {
  2293.     extern enum mdep_cc_info next_cc_use ( );
  2294.     extern rtx next_cc_relevancy ( );
  2295.     rtx relevant_insn, relevant_body;
  2296.     
  2297.     /* sometimes this compiler manages attempt ( compare ( reg x ) ( reg x )).
  2298.        the condition codes implied by this are obvious. we peek down the insn
  2299.        chain and discover the next_cc0_relevancy ( ). if we discover
  2300.        that the ccs are being set gratuitiously, we ignore this compare, 
  2301.        otherwise we change the cc0 consumer to be a constant load in the case
  2302.        of an Scond or a hard branch or nop in the case of a Bcond. */
  2303.  
  2304.     if ( REGNO ( operands[0] ) == REGNO ( operands[1] ))
  2305.     {
  2306.     relevant_insn = next_cc_relevancy ( insn );
  2307.     relevant_body = PATTERN ( relevant_insn );
  2308.     
  2309.     if ( JUMP_INSN == GET_CODE ( relevant_insn ))
  2310.     {
  2311.         if (( IF_THEN_ELSE == GET_CODE ( relevant_body =
  2312.                         XEXP ( relevant_body, 1 ))) &&
  2313.         ( CONST_INT != 
  2314.          GET_CODE ( XEXP ( relevant_body, 0 ))))
  2315.         {
  2316.         if (( GEU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2317.             ( GE == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2318.             ( LEU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2319.             ( LE == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2320.             ( EQU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2321.             ( EQ == GET_CODE ( XEXP ( relevant_body, 0 ))))
  2322.         {
  2323.             /* change ineq into const1_rtx because x == x always. */
  2324.  
  2325.             if ( pc_rtx == XEXP ( XEXP ( PATTERN ( relevant_insn ),
  2326.                         1 ), 1 ))
  2327.             {
  2328.             delete_insn ( relevant_insn );
  2329.             }
  2330.             else
  2331.             {
  2332.             INSN_CODE ( relevant_insn ) = -1;
  2333.  
  2334.             XEXP ( PATTERN ( relevant_insn ), 1 ) =
  2335.                 XEXP ( XEXP ( PATTERN ( relevant_insn ), 1 ), 1 );
  2336.             }
  2337.         }
  2338.         else
  2339.         {
  2340.             /* otherwise change ineq into const0_rtx. */
  2341.             
  2342.             if ( pc_rtx == XEXP ( XEXP ( PATTERN ( relevant_insn ),
  2343.                         1 ), 1 ))
  2344.             {
  2345.             INSN_CODE ( relevant_insn ) = -1;
  2346.  
  2347.             XEXP ( PATTERN ( relevant_insn ), 1 ) =
  2348.                 XEXP ( XEXP ( PATTERN ( relevant_insn ), 1 ), 2 );
  2349.             }
  2350.             else
  2351.             {
  2352.             delete_insn ( relevant_insn );
  2353.             }
  2354.         }
  2355.         }
  2356.     }
  2357.     else if (( INSN == GET_CODE ( relevant_insn )) &&
  2358.          ( PARALLEL == GET_CODE ( relevant_body )) &&
  2359.          ( SET == GET_CODE ( relevant_body = 
  2360.                     XVECEXP ( relevant_body, 0, 0 ))) &&
  2361.          ( 0 == strcmp ( \"ee\",
  2362.                 GET_RTX_FORMAT ( GET_CODE ( XEXP ( relevant_body, 1 ))))) &&
  2363.          ( cc0_rtx == XEXP ( XEXP ( relevant_body, 1 ), 0 )))
  2364.     {
  2365.         if (( GEU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2366.         ( GE == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2367.         ( LEU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2368.         ( LE == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2369.         ( EQU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2370.         ( EQ == GET_CODE ( XEXP ( relevant_body, 1 ))))
  2371.         {
  2372.         /* change ineq into const1_rtx because x == x always. */
  2373.  
  2374.         XEXP ( relevant_body, 1 ) = const1_rtx;
  2375.         }
  2376.         else 
  2377.         {
  2378.         /* otherwise change ineq into const0_rtx. */
  2379.  
  2380.         XEXP ( relevant_body, 1 ) = const0_rtx;
  2381.         }
  2382.         INSN_CODE ( relevant_insn ) = -1;
  2383.     }
  2384.     return \"\";
  2385.     }
  2386.     
  2387.     cc_status.mdep = CC_UNSIGNED;
  2388.  
  2389.     return \"move    #0,%k0\;move    #0,%k1\;cmp    %1,%0\";
  2390. }" )
  2391.  
  2392. ( define_insn "cmpsi"
  2393.   [ ( set ( cc0 )
  2394.           ( compare ( match_operand:SI 0 "register_operand" "D" )
  2395.                     ( match_operand:SI 1 "register_operand" "*S*D" )))
  2396.   ]
  2397.   ""
  2398.   "*
  2399. {
  2400.     extern enum mdep_cc_info next_cc_use ( );
  2401.     extern rtx next_cc_relevancy ( );
  2402.     rtx relevant_insn, relevant_body;
  2403.     
  2404.     /* sometimes this compiler manages attempt ( compare ( reg x ) ( reg x )).
  2405.        the condition codes implied by this are obvious. we peek down the insn
  2406.        chain and discover the next_cc0_relevancy ( ). if we discover
  2407.        that the ccs are being set gratuitiously, we ignore this compare, 
  2408.        otherwise we change the cc0 consumer to be a constant load in the case
  2409.        of an Scond or a hard branch or nop in the case of a Bcond. */
  2410.  
  2411.     if ( REGNO ( operands[0] ) == REGNO ( operands[1] ))
  2412.     {
  2413.     relevant_insn = next_cc_relevancy ( insn );
  2414.     relevant_body = PATTERN ( relevant_insn );
  2415.     
  2416.     if ( JUMP_INSN == GET_CODE ( relevant_insn ))
  2417.     {
  2418.         if (( IF_THEN_ELSE == GET_CODE ( relevant_body =
  2419.                         XEXP ( relevant_body, 1 ))) &&
  2420.         ( CONST_INT != 
  2421.          GET_CODE ( XEXP ( relevant_body, 0 ))))
  2422.         {
  2423.         if (( GEU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2424.             ( GE == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2425.             ( LEU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2426.             ( LE == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2427.             ( EQU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2428.             ( EQ == GET_CODE ( XEXP ( relevant_body, 0 ))))
  2429.         {
  2430.             /* change ineq into const1_rtx because x == x always. */
  2431.  
  2432.             if ( pc_rtx == XEXP ( XEXP ( PATTERN ( relevant_insn ),
  2433.                         1 ), 1 ))
  2434.             {
  2435.             delete_insn ( relevant_insn );
  2436.             }
  2437.             else
  2438.             {
  2439.             INSN_CODE ( relevant_insn ) = -1;
  2440.  
  2441.             XEXP ( PATTERN ( relevant_insn ), 1 ) =
  2442.                 XEXP ( XEXP ( PATTERN ( relevant_insn ), 1 ), 1 );
  2443.             }
  2444.         }
  2445.         else
  2446.         {
  2447.             /* otherwise change ineq into const0_rtx. */
  2448.             
  2449.             if ( pc_rtx == XEXP ( XEXP ( PATTERN ( relevant_insn ),
  2450.                         1 ), 1 ))
  2451.             {
  2452.             INSN_CODE ( relevant_insn ) = -1;
  2453.  
  2454.             XEXP ( PATTERN ( relevant_insn ), 1 ) =
  2455.                 XEXP ( XEXP ( PATTERN ( relevant_insn ), 1 ), 2 );
  2456.             }
  2457.             else
  2458.             {
  2459.             delete_insn ( relevant_insn );
  2460.             }
  2461.         }
  2462.         }
  2463.     }
  2464.     else if (( INSN == GET_CODE ( relevant_insn )) &&
  2465.          ( PARALLEL == GET_CODE ( relevant_body )) &&
  2466.          ( SET == GET_CODE ( relevant_body = 
  2467.                     XVECEXP ( relevant_body, 0, 0 ))) &&
  2468.          ( 0 == strcmp ( \"ee\",
  2469.                 GET_RTX_FORMAT ( GET_CODE ( XEXP ( relevant_body, 1 ))))) &&
  2470.          ( cc0_rtx == XEXP ( XEXP ( relevant_body, 1 ), 0 )))
  2471.     {
  2472.         if (( GEU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2473.         ( GE == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2474.         ( LEU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2475.         ( LE == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2476.         ( EQU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2477.         ( EQ == GET_CODE ( XEXP ( relevant_body, 1 ))))
  2478.         {
  2479.         /* change ineq into const1_rtx because x == x always. */
  2480.  
  2481.         XEXP ( relevant_body, 1 ) = const1_rtx;
  2482.         }
  2483.         else 
  2484.         {
  2485.         /* otherwise change ineq into const0_rtx. */
  2486.  
  2487.         XEXP ( relevant_body, 1 ) = const0_rtx;
  2488.         }
  2489.         INSN_CODE ( relevant_insn ) = -1;
  2490.     }
  2491.     return \"\";
  2492.     }    
  2493.  
  2494.     cc_status.mdep = CC_SIGNED;
  2495.  
  2496.     return \"cmp    %1,%0\";
  2497. }" )
  2498.  
  2499. ( define_insn ""
  2500.   [ ( set ( cc0 )
  2501.           ( compare ( match_operand:DI 0 "register_operand" "D" )
  2502.                     ( match_operand:DI 1 "register_operand" "D" )))
  2503.   ]
  2504.   "UNSIGNED_COMPARE_P( insn )"
  2505.   "*
  2506. {
  2507.     extern enum mdep_cc_info next_cc_use ( );
  2508.     extern rtx next_cc_relevancy ( );
  2509.     rtx relevant_insn, relevant_body;
  2510.     
  2511.     /* sometimes this compiler manages attempt ( compare ( reg x ) ( reg x )).
  2512.        the condition codes implied by this are obvious. we peek down the insn
  2513.        chain and discover the next_cc0_relevancy ( ). if we discover
  2514.        that the ccs are being set gratuitiously, we ignore this compare, 
  2515.        otherwise we change the cc0 consumer to be a constant load in the case
  2516.        of an Scond or a hard branch or nop in the case of a Bcond. */
  2517.  
  2518.     if ( REGNO ( operands[0] ) == REGNO ( operands[1] ))
  2519.     {
  2520.     relevant_insn = next_cc_relevancy ( insn );
  2521.     relevant_body = PATTERN ( relevant_insn );
  2522.     
  2523.     if ( JUMP_INSN == GET_CODE ( relevant_insn ))
  2524.     {
  2525.         if (( IF_THEN_ELSE == GET_CODE ( relevant_body =
  2526.                         XEXP ( relevant_body, 1 ))) &&
  2527.         ( CONST_INT != 
  2528.          GET_CODE ( XEXP ( relevant_body, 0 ))))
  2529.         {
  2530.         if (( GEU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2531.             ( GE == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2532.             ( LEU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2533.             ( LE == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2534.             ( EQU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2535.             ( EQ == GET_CODE ( XEXP ( relevant_body, 0 ))))
  2536.         {
  2537.             /* change ineq into const1_rtx because x == x always. */
  2538.  
  2539.             if ( pc_rtx == XEXP ( XEXP ( PATTERN ( relevant_insn ),
  2540.                         1 ), 1 ))
  2541.             {
  2542.             delete_insn ( relevant_insn );
  2543.             }
  2544.             else
  2545.             {
  2546.             INSN_CODE ( relevant_insn ) = -1;
  2547.  
  2548.             XEXP ( PATTERN ( relevant_insn ), 1 ) =
  2549.                 XEXP ( XEXP ( PATTERN ( relevant_insn ), 1 ), 1 );
  2550.             }
  2551.         }
  2552.         else
  2553.         {
  2554.             /* otherwise change ineq into const0_rtx. */
  2555.             
  2556.             if ( pc_rtx == XEXP ( XEXP ( PATTERN ( relevant_insn ),
  2557.                         1 ), 1 ))
  2558.             {
  2559.             INSN_CODE ( relevant_insn ) = -1;
  2560.  
  2561.             XEXP ( PATTERN ( relevant_insn ), 1 ) =
  2562.                 XEXP ( XEXP ( PATTERN ( relevant_insn ), 1 ), 2 );
  2563.             }
  2564.             else
  2565.             {
  2566.             delete_insn ( relevant_insn );
  2567.             }
  2568.         }
  2569.         }
  2570.     }
  2571.     else if (( INSN == GET_CODE ( relevant_insn )) &&
  2572.          ( PARALLEL == GET_CODE ( relevant_body )) &&
  2573.          ( SET == GET_CODE ( relevant_body = 
  2574.                     XVECEXP ( relevant_body, 0, 0 ))) &&
  2575.          ( 0 == strcmp ( \"ee\",
  2576.                 GET_RTX_FORMAT ( GET_CODE ( XEXP ( relevant_body, 1 ))))) &&
  2577.          ( cc0_rtx == XEXP ( XEXP ( relevant_body, 1 ), 0 )))
  2578.     {
  2579.         if (( GEU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2580.         ( GE == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2581.         ( LEU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2582.         ( LE == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2583.         ( EQU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2584.         ( EQ == GET_CODE ( XEXP ( relevant_body, 1 ))))
  2585.         {
  2586.         /* change ineq into const1_rtx because x == x always. */
  2587.  
  2588.         XEXP ( relevant_body, 1 ) = const1_rtx;
  2589.         }
  2590.         else 
  2591.         {
  2592.         /* otherwise change ineq into const0_rtx. */
  2593.  
  2594.         XEXP ( relevant_body, 1 ) = const0_rtx;
  2595.         }
  2596.         INSN_CODE ( relevant_insn ) = -1;
  2597.     }
  2598.     return \"\";
  2599.     }
  2600.     
  2601.     cc_status.mdep = CC_UNSIGNED;
  2602.  
  2603.     return \"move    #0,%k0\;move    #0,%k1\;cmp    %1,%0\";
  2604. }" )
  2605.  
  2606. ( define_insn "cmpdi"
  2607.   [ ( set ( cc0 )
  2608.           ( compare ( match_operand:DI 0 "register_operand" "D" )
  2609.                     ( match_operand:DI 1 "register_operand" "D" )))
  2610.   ]
  2611.   ""
  2612.   "*
  2613. {
  2614.     extern enum mdep_cc_info next_cc_use ( );
  2615.     extern rtx next_cc_relevancy ( );
  2616.     rtx relevant_insn, relevant_body;
  2617.     
  2618.     /* sometimes this compiler manages attempt ( compare ( reg x ) ( reg x )).
  2619.        the condition codes implied by this are obvious. we peek down the insn
  2620.        chain and discover the next_cc0_relevancy ( ). if we discover
  2621.        that the ccs are being set gratuitiously, we ignore this compare, 
  2622.        otherwise we change the cc0 consumer to be a constant load in the case
  2623.        of an Scond or a hard branch or nop in the case of a Bcond. */
  2624.  
  2625.     if ( REGNO ( operands[0] ) == REGNO ( operands[1] ))
  2626.     {
  2627.     relevant_insn = next_cc_relevancy ( insn );
  2628.     relevant_body = PATTERN ( relevant_insn );
  2629.     
  2630.     if ( JUMP_INSN == GET_CODE ( relevant_insn ))
  2631.     {
  2632.         if (( IF_THEN_ELSE == GET_CODE ( relevant_body =
  2633.                         XEXP ( relevant_body, 1 ))) &&
  2634.         ( CONST_INT != 
  2635.          GET_CODE ( XEXP ( relevant_body, 0 ))))
  2636.         {
  2637.         if (( GEU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2638.             ( GE == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2639.             ( LEU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2640.             ( LE == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2641.             ( EQU == GET_CODE ( XEXP ( relevant_body, 0 ))) ||
  2642.             ( EQ == GET_CODE ( XEXP ( relevant_body, 0 ))))
  2643.         {
  2644.             /* change ineq into const1_rtx because x == x always. */
  2645.  
  2646.             if ( pc_rtx == XEXP ( XEXP ( PATTERN ( relevant_insn ),
  2647.                         1 ), 1 ))
  2648.             {
  2649.             delete_insn ( relevant_insn );
  2650.             }
  2651.             else
  2652.             {
  2653.             INSN_CODE ( relevant_insn ) = -1;
  2654.  
  2655.             XEXP ( PATTERN ( relevant_insn ), 1 ) =
  2656.                 XEXP ( XEXP ( PATTERN ( relevant_insn ), 1 ), 1 );
  2657.             }
  2658.         }
  2659.         else
  2660.         {
  2661.             /* otherwise change ineq into const0_rtx. */
  2662.             
  2663.             if ( pc_rtx == XEXP ( XEXP ( PATTERN ( relevant_insn ),
  2664.                         1 ), 1 ))
  2665.             {
  2666.             INSN_CODE ( relevant_insn ) = -1;
  2667.  
  2668.             XEXP ( PATTERN ( relevant_insn ), 1 ) =
  2669.                 XEXP ( XEXP ( PATTERN ( relevant_insn ), 1 ), 2 );
  2670.             }
  2671.             else
  2672.             {
  2673.             delete_insn ( relevant_insn );
  2674.             }
  2675.         }
  2676.         }
  2677.     }
  2678.     else if (( INSN == GET_CODE ( relevant_insn )) &&
  2679.          ( PARALLEL == GET_CODE ( relevant_body )) &&
  2680.          ( SET == GET_CODE ( relevant_body = 
  2681.                     XVECEXP ( relevant_body, 0, 0 ))) &&
  2682.          ( 0 == strcmp ( \"ee\",
  2683.                 GET_RTX_FORMAT ( GET_CODE ( XEXP ( relevant_body, 1 ))))) &&
  2684.          ( cc0_rtx == XEXP ( XEXP ( relevant_body, 1 ), 0 )))
  2685.     {
  2686.         if (( GEU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2687.         ( GE == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2688.         ( LEU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2689.         ( LE == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2690.         ( EQU == GET_CODE ( XEXP ( relevant_body, 1 ))) ||
  2691.         ( EQ == GET_CODE ( XEXP ( relevant_body, 1 ))))
  2692.         {
  2693.         /* change ineq into const1_rtx because x == x always. */
  2694.  
  2695.         XEXP ( relevant_body, 1 ) = const1_rtx;
  2696.         }
  2697.         else 
  2698.         {
  2699.         /* otherwise change ineq into const0_rtx. */
  2700.  
  2701.         XEXP ( relevant_body, 1 ) = const0_rtx;
  2702.         }
  2703.         INSN_CODE ( relevant_insn ) = -1;
  2704.     }
  2705.     return \"\";
  2706.     }
  2707.     
  2708.     cc_status.mdep = CC_SIGNED;
  2709.  
  2710.     return \"cmp    %1,%0\";
  2711. }" )
  2712.  
  2713. ;;
  2714. ;;  ...........................................................................
  2715. ;;
  2716. ;;          TESTS
  2717. ;;
  2718. ;;  ...........................................................................
  2719. ;;
  2720.  
  2721. ( define_insn "tstpsi"
  2722.   [ ( set ( cc0 )
  2723.       ( match_operand:PSI 0 "register_operand" "D" )) ]
  2724.   ""
  2725.   "*
  2726. {
  2727.     if ( CC_UNSIGNED == ( cc_status.mdep = next_cc_use ( insn )))
  2728.     {
  2729.     return \"move    #0,%k0\;tst    %0\";
  2730.     }
  2731.     else
  2732.     {
  2733.     return \"tst    %0\";
  2734.     }
  2735. }" )
  2736.  
  2737. ( define_insn "tstsi"
  2738.   [ ( set ( cc0 )
  2739.       ( match_operand:SI 0 "register_operand" "D" )) ]
  2740.   ""
  2741.   "*
  2742. {
  2743.     if ( CC_UNSIGNED == ( cc_status.mdep = next_cc_use ( insn )))
  2744.     {
  2745.     return \"move    #0,%k0\;tst    %0\";
  2746.     }
  2747.     else
  2748.     {
  2749.     return \"tst    %0\";
  2750.     }
  2751. }" )
  2752.  
  2753. ( define_insn "tstdi"
  2754.   [ ( set ( cc0 )
  2755.       ( match_operand:DI 0 "general_operand" "D" )) ]
  2756.   ""
  2757.   "*
  2758. {
  2759.     if ( CC_UNSIGNED == ( cc_status.mdep = next_cc_use ( insn )))
  2760.     {
  2761.     return \"move    #0,%k0\;tst    %0\";
  2762.     }
  2763.     else
  2764.     {
  2765.     return \"tst    %0\";
  2766.     }
  2767. }" )
  2768.  
  2769. ;;
  2770. ;;  ...........................................................................
  2771. ;;
  2772. ;;          SCALAR CONVERSIONS USING TRUNCATION
  2773. ;;
  2774. ;;  ...........................................................................
  2775. ;;
  2776.  
  2777. ( define_insn "truncsipsi2"
  2778.   [ ( set ( match_operand:PSI 0 "register_operand" "=A" )
  2779.       ( truncate:PSI
  2780.         ( match_operand:SI 1 "register_operand" "=*S*D" )))
  2781.   ]
  2782.   ""
  2783.   "move    %e1,%0" )
  2784.  
  2785. ( define_insn "truncdisi2"
  2786.   [ ( set ( match_operand:SI 0 "general_operand" "=*S*D" )
  2787.       ( truncate:SI
  2788.         ( match_operand:DI 1 "general_operand" "*S*D" )))
  2789.   ]
  2790.   ""
  2791.   "*
  2792. {
  2793.     switch ( which_alternative )
  2794.     {
  2795.     case 0:
  2796.     if ( IS_SRC_OR_MPY_P ( REGNO ( operands[1] )))
  2797.     {
  2798.         return \"move    %g1,%0\";
  2799.     }
  2800.     else
  2801.     {
  2802.         return \"move    %h1,%0\";
  2803.     }
  2804.     }
  2805. }")
  2806.     
  2807. ;;
  2808. ;;  ...........................................................................
  2809. ;;
  2810. ;;          SCALAR CONVERSIONS USING ZERO EXTENSION
  2811. ;;
  2812. ;;  ...........................................................................
  2813. ;;
  2814.  
  2815. ( define_expand "zero_extendqisi2"
  2816.   [ ( set ( match_operand:SI 0 "register_operand" "" )
  2817.       ( zero_extend:SI
  2818.         ( match_operand:QI 1 "register_operand" "" )))
  2819.   ]
  2820.   ""
  2821.   "
  2822. {
  2823.     if ( SUBREG == GET_CODE ( operands[1] ))
  2824.     {
  2825.     operands[1] = copy_rtx ( SUBREG_REG ( operands[1] ));
  2826.     }
  2827.     else
  2828.     {
  2829.     operands[1] = copy_rtx ( operands[1] );
  2830.     }    
  2831.     operands[1] = gen_rtx ( SUBREG, SImode, operands[1], 0 );
  2832.     
  2833.     emit_insn ( gen_rtx ( SET, VOIDmode, operands[0], operands[1] ));
  2834.  
  2835.     DONE;
  2836. }" )
  2837.  
  2838. ( define_insn "zero_extendpsisi2"
  2839.   [ ( set ( match_operand:SI 0 "general_operand" "=*D*S" )
  2840.       ( zero_extend:SI 
  2841.         ( match_operand:PSI 1 "general_operand" "*A*D*S" )))
  2842.   ]
  2843.   ""
  2844.   "*
  2845. {
  2846.     /* we may want to add mem-ref as an opt. later. */
  2847.  
  2848.     if ( REGNO ( operands[0] ) == REGNO ( operands[1] ))
  2849.     {
  2850.     return \"\";
  2851.     }
  2852.     
  2853.     return \"move    %1,%0\";
  2854. }")
  2855.  
  2856. ( define_insn "zero_extendsidi2"
  2857.   [ ( set ( match_operand:DI 0 "general_operand" "=&*S*D" )
  2858.       ( zero_extend:DI 
  2859.         ( match_operand:SI 1 "general_operand" "*S*D" )))
  2860.   ]
  2861.   ""
  2862.   "*
  2863. {
  2864.     if ( DST_REGS == REGNO_REG_CLASS ( REGNO ( operands[0] )))
  2865.     {
  2866.     return \"clr    %0\;move    %1,%h0\";
  2867.     }
  2868.     else
  2869.     {
  2870.     return \"move    %1,%0\;move    #0,%g0\";
  2871.     }
  2872. }")
  2873.  
  2874. ;;
  2875. ;;  ...........................................................................
  2876. ;;
  2877. ;;          SCALAR CONVERSIONS USING SIGN EXTENSION
  2878. ;;
  2879. ;;  ...........................................................................
  2880. ;;
  2881.  
  2882. ( define_expand "extendqisi2"
  2883.   [ ( set ( match_operand:SI 0 "register_operand" "" )
  2884.       ( sign_extend:SI
  2885.         ( match_operand:QI 1 "register_operand" "" )))
  2886.   ]
  2887.   ""
  2888.   "
  2889. {
  2890.     if ( SUBREG == GET_CODE ( operands[1] ))
  2891.     {
  2892.     operands[1] = copy_rtx ( SUBREG_REG ( operands[1] ));
  2893.     }
  2894.     else
  2895.     {
  2896.     operands[1] = copy_rtx ( operands[1] );
  2897.     }
  2898.     operands[1] = gen_rtx ( SUBREG, SImode, operands[1], 0 );
  2899.     
  2900.     emit_insn ( gen_rtx ( SET, VOIDmode, operands[0], operands[1] ));
  2901.  
  2902.     DONE;
  2903. }" )
  2904.  
  2905. ( define_insn "extendsidi2"
  2906.   [ ( set ( match_operand:DI 0 "general_operand" "=S" )
  2907.       ( sign_extend:DI 
  2908.         ( match_operand:SI 1 "general_operand" "D" )))
  2909.   ]
  2910.   ""
  2911.   "move    %e1,%0\;move    %k1,%g0" )
  2912.  
  2913. ( define_insn "extendpsisi2"
  2914.   [ ( set ( match_operand:SI 0 "general_operand" "=D" )
  2915.       ( sign_extend:SI 
  2916.         ( match_operand:PSI 1 "general_operand" "*A*S" )))
  2917.   ]
  2918.   ""
  2919.   "*
  2920. {
  2921.     /* we may want to add mem-ref as an opt. later. */
  2922.  
  2923.     if ( DST_REGS == REGNO_REG_CLASS ( REGNO ( operands[0] )) &&
  2924.     ADDR_REGS != REGNO_REG_CLASS ( REGNO ( operands[1] )) &&
  2925.     ! MEM_IN_STRUCT_P ( operands[0] ) &&
  2926.     ! MEM_IN_STRUCT_P ( operands[1] ))
  2927.     {
  2928.     return \"tfr    %1,%0\";
  2929.     }
  2930.     else
  2931.     {
  2932.     return \"move    %1,%0\";
  2933.     }
  2934. }")
  2935.  
  2936. ;;
  2937. ;;  ...........................................................................
  2938. ;;
  2939. ;;          CONVERSIONS BETWEEN FLOAT AND DOUBLE
  2940. ;;
  2941. ;;  ...........................................................................
  2942. ;;
  2943.  
  2944. ;;
  2945. ;;  ...........................................................................
  2946. ;;
  2947. ;;          CONVERSIONS BETWEEN FLOATING POINT AND INTEGER
  2948. ;;
  2949. ;;  ...........................................................................
  2950. ;;
  2951.  
  2952.  ;; Using the signed routine at this point - this is a bug.
  2953.  
  2954. ( define_insn "floatunssidf2"
  2955.   [ ( set ( match_operand:DF 0 "register_operand" "=D" )
  2956.       ( unsigned_float:DF 
  2957.         ( match_operand:SI 1 "register_operand" "0" )))
  2958.   ]
  2959.   ""
  2960.   "*
  2961. {
  2962.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  2963.     {
  2964.     return \"jsr    floatsidf_a\";
  2965.     }
  2966.     else
  2967.     {
  2968.     return \"jsr    floatsidf_b\";
  2969.     }
  2970. }" )
  2971.  
  2972.  ;; Using the signed routine at this point - this is a bug.
  2973.  
  2974. ( define_insn "floatunssisf2"
  2975.   [ ( set ( match_operand:SF 0 "register_operand" "=D" )
  2976.       ( unsigned_float:SF 
  2977.         ( match_operand:SI 1 "register_operand" "0" )))
  2978.   ]
  2979.   ""
  2980.   "*
  2981. {
  2982.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  2983.     {
  2984.     return \"jsr    floatsidf_a\";
  2985.     }
  2986.     else
  2987.     {
  2988.     return \"jsr    floatsidf_b\";
  2989.     }
  2990. }" )
  2991.  
  2992. ( define_insn "floatsidf2"
  2993.   [ ( set ( match_operand:DF 0 "register_operand" "=D" )
  2994.       ( float:DF 
  2995.         ( match_operand:SI 1 "register_operand" "0" )))
  2996.   ]
  2997.   ""
  2998.   "*
  2999. {
  3000.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3001.     {
  3002.     return \"jsr    floatsidf_a\";
  3003.     }
  3004.     else
  3005.     {
  3006.     return \"jsr    floatsidf_b\";
  3007.     }
  3008. }" )
  3009.     
  3010. ( define_insn "floatsisf2"
  3011.   [ ( set ( match_operand:SF 0 "register_operand" "=D" )
  3012.       ( float:SF 
  3013.         ( match_operand:SI 1 "register_operand" "0" )))
  3014.   ]
  3015.   ""
  3016.   "*
  3017. {
  3018.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3019.     {
  3020.     return \"jsr    floatsidf_a\";
  3021.     }
  3022.     else
  3023.     {
  3024.     return \"jsr    floatsidf_b\";
  3025.     }
  3026. }" )
  3027.  
  3028. ( define_insn "fixdfsi2"
  3029.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3030.       ( fix:SI 
  3031.         ( match_operand:DF 1 "register_operand" "0" )))
  3032.   ]
  3033.   ""
  3034.   "*
  3035. {
  3036.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3037.     {
  3038.     return \"jsr    fixdfsi_a\";
  3039.     }
  3040.     else
  3041.     {
  3042.     return \"jsr    fixdfsi_b\";
  3043.     }
  3044. }" )
  3045.  
  3046. ( define_insn "fixsfsi2"
  3047.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3048.       ( fix:SI 
  3049.         ( match_operand:SF 1 "register_operand" "0" )))
  3050.   ]
  3051.   ""
  3052.   "*
  3053. {
  3054.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3055.     {
  3056.     return \"jsr    fixdfsi_a\";
  3057.     }
  3058.     else
  3059.     {
  3060.     return \"jsr    fixdfsi_b\";
  3061.     }
  3062. }" )
  3063.  
  3064. ( define_insn "fixunsdfsi2"
  3065.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3066.       ( unsigned_fix:SI 
  3067.         ( match_operand:DF 1 "register_operand" "0" )))
  3068.   ]
  3069.   ""
  3070.   "*
  3071. {
  3072.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3073.     {
  3074.     return \"jsr    fixunsdfsi_a\";
  3075.     }
  3076.     else
  3077.     {
  3078.     return \"jsr    fixunsdfsi_b\";
  3079.     }
  3080. }" )
  3081.  
  3082. ( define_insn "fixunssfsi2"
  3083.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3084.       ( unsigned_fix:SI 
  3085.         ( match_operand:SF 1 "register_operand" "0" )))
  3086.   ]
  3087.   ""
  3088.   "*
  3089. {
  3090.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3091.     {
  3092.     return \"jsr    fixunsdfsi_a\";
  3093.     }
  3094.     else
  3095.     {
  3096.     return \"jsr    fixunsdfsi_b\";
  3097.     }
  3098. }" )
  3099.  
  3100.  ;; Using the signed routine at this point - this is a bug.
  3101.  
  3102. ( define_insn "floatunsdidf2"
  3103.   [ ( set ( match_operand:DF 0 "register_operand" "=D" )
  3104.       ( unsigned_float:DF 
  3105.         ( match_operand:DI 1 "register_operand" "0" )))
  3106.   ]
  3107.   ""
  3108.   "*
  3109. {
  3110.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3111.     {
  3112.     return \"jsr    floatdidf_a\";
  3113.     }
  3114.     else
  3115.     {
  3116.     return \"jsr    floatdidf_b\";
  3117.     }
  3118. }" )
  3119.  
  3120.  ;; Using the signed routine at this point - this is a bug.
  3121.  
  3122. ( define_insn "floatunsdisf2"
  3123.   [ ( set ( match_operand:SF 0 "register_operand" "=D" )
  3124.       ( unsigned_float:SF 
  3125.         ( match_operand:DI 1 "register_operand" "0" )))
  3126.   ]
  3127.   ""
  3128.   "*
  3129. {
  3130.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3131.     {
  3132.     return \"jsr    floatdidf_a\";
  3133.     }
  3134.     else
  3135.     {
  3136.     return \"jsr    floatdidf_b\";
  3137.     }
  3138. }" )
  3139.  
  3140. ( define_insn "floatdidf2"
  3141.   [ ( set ( match_operand:DF 0 "register_operand" "=D" )
  3142.       ( float:DF 
  3143.         ( match_operand:DI 1 "register_operand" "0" )))
  3144.   ]
  3145.   ""
  3146.   "*
  3147. {
  3148.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3149.     {
  3150.     return \"jsr    floatdidf_a\";
  3151.     }
  3152.     else
  3153.     {
  3154.     return \"jsr    floatdidf_b\";
  3155.     }
  3156. }" )
  3157.     
  3158. ( define_insn "floatdisf2"
  3159.   [ ( set ( match_operand:SF 0 "register_operand" "=D" )
  3160.       ( float:SF 
  3161.         ( match_operand:DI 1 "register_operand" "0" )))
  3162.   ]
  3163.   ""
  3164.   "*
  3165. {
  3166.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3167.     {
  3168.     return \"jsr    floatdidf_a\";
  3169.     }
  3170.     else
  3171.     {
  3172.     return \"jsr    floatdidf_b\";
  3173.     }
  3174. }" )
  3175.  
  3176. ( define_insn "fixdfdi2"
  3177.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  3178.       ( fix:DI 
  3179.         ( match_operand:DF 1 "register_operand" "0" )))
  3180.   ]
  3181.   ""
  3182.   "*
  3183. {
  3184.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3185.     {
  3186.     return \"jsr    fixdfdi_a\";
  3187.     }
  3188.     else
  3189.     {
  3190.     return \"jsr    fixdfdi_b\";
  3191.     }
  3192. }" )
  3193.  
  3194. ( define_insn "fixsfdi2"
  3195.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  3196.       ( fix:DI 
  3197.         ( match_operand:SF 1 "register_operand" "0" )))
  3198.   ]
  3199.   ""
  3200.   "*
  3201. {
  3202.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3203.     {
  3204.     return \"jsr    fixdfdi_a\";
  3205.     }
  3206.     else
  3207.     {
  3208.     return \"jsr    fixdfdi_b\";
  3209.     }
  3210. }" )
  3211.  
  3212. ( define_insn "fixunsdfdi2"
  3213.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  3214.       ( unsigned_fix:DI 
  3215.         ( match_operand:DF 1 "register_operand" "0" )))
  3216.   ]
  3217.   ""
  3218.   "*
  3219. {
  3220.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3221.     {
  3222.     return \"jsr    fixunsdfdi_a\";
  3223.     }
  3224.     else
  3225.     {
  3226.     return \"jsr    fixunsdfdi_b\";
  3227.     }
  3228. }" )
  3229.  
  3230. ( define_insn "fixunssfdi2"
  3231.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  3232.       ( unsigned_fix:DI 
  3233.         ( match_operand:SF 1 "register_operand" "0" )))
  3234.   ]
  3235.   ""
  3236.   "*
  3237. {
  3238.     if ( DSP56_A_REGNUM == REGNO ( operands[0] ))
  3239.     {
  3240.     return \"jsr    fixunsdfdi_a\";
  3241.     }
  3242.     else
  3243.     {
  3244.     return \"jsr    fixunsdfdi_b\";
  3245.     }
  3246. }" )
  3247.  
  3248. ( define_expand "fix_truncdfsi2"
  3249.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3250.       ( fix:SI 
  3251.         ( match_operand:DF 1 "register_operand" "0" )))
  3252.   ]
  3253.   ""
  3254.   "" )
  3255.  
  3256. ( define_expand "fix_truncsfsi2"
  3257.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3258.       ( fix:SI 
  3259.         ( match_operand:SF 1 "register_operand" "0" )))
  3260.   ]
  3261.   ""
  3262.   "" )
  3263.  
  3264. ( define_expand "fixuns_truncdfsi2"
  3265.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3266.       ( unsigned_fix:SI 
  3267.         ( match_operand:DF 1 "register_operand" "0" )))
  3268.   ]
  3269.   ""
  3270.   "" )
  3271.  
  3272. ( define_expand "fixuns_truncsfsi2"
  3273.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3274.       ( unsigned_fix:SI 
  3275.         ( match_operand:SF 1 "register_operand" "0" )))
  3276.   ]
  3277.   ""
  3278.   "" )
  3279.  
  3280. ( define_expand "fix_truncdfdi2"
  3281.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  3282.       ( fix:DI 
  3283.         ( match_operand:DF 1 "register_operand" "0" )))
  3284.   ]
  3285.   ""
  3286.   "" )
  3287.  
  3288. ( define_expand "fix_truncsfdi2"
  3289.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  3290.       ( fix:DI 
  3291.         ( match_operand:SF 1 "register_operand" "0" )))
  3292.   ]
  3293.   ""
  3294.   "" )
  3295.  
  3296. ( define_expand "fixuns_truncdfdi2"
  3297.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  3298.       ( unsigned_fix:DI 
  3299.         ( match_operand:DF 1 "register_operand" "0" )))
  3300.   ]
  3301.   ""
  3302.   "" )
  3303.  
  3304. ( define_expand "fixuns_truncsfdi2"
  3305.   [ ( set ( match_operand:DI 0 "register_operand" "=D" )
  3306.       ( unsigned_fix:DI 
  3307.         ( match_operand:SF 1 "register_operand" "0" )))
  3308.   ]
  3309.   ""
  3310.   "" )
  3311.  
  3312. ;;
  3313. ;;  ...........................................................................
  3314. ;;
  3315. ;;          CONDITIONAL JUMPS
  3316. ;;
  3317. ;;  ...........................................................................
  3318. ;;
  3319.  
  3320. ( define_insn "do"
  3321.   [ ( parallel
  3322.       [ ( clobber ( cc0 ))
  3323.     ( use ( match_operand:SI 0 "general_operand" "*D*S,J" ))
  3324.     ( set ( pc ) ( if_then_else ( eq ( cc0 ) ( const_int 0 ))
  3325.                     ( label_ref ( match_operand 1 "" "" ))
  3326.                     ( pc )))
  3327.       ] )
  3328.   ]
  3329.   ""
  3330.   "*
  3331. {
  3332.     extern void record_address_regs_used ( );
  3333.     
  3334.     /* we must scan forward and make sure that there is at least one non-do
  3335.      * insn between this insn and the target label. If not, 86 the loop. 
  3336.      * BTW, a nop instruction doesn't count.
  3337.      */
  3338.     rtx scan = insn;
  3339.     
  3340.     while ( scan && ( operands[1] != scan ))
  3341.     {
  3342.     if (( INSN == GET_CODE ( scan )) && 
  3343.         ( const0_rtx != PATTERN ( scan )))
  3344.     {
  3345.         break;
  3346.     }
  3347.         scan = NEXT_INSN ( scan );
  3348.     }
  3349.     
  3350.     if ( ! scan )
  3351.     {
  3352.     /* do without corresponding od ! */
  3353.     abort ( );
  3354.     }
  3355.     if (( scan == operands[1] ) ||
  3356.     ( which_alternative && ( 1 == INTVAL ( operands[0] ))))
  3357.     {
  3358.     /* we're not really doing a do; record that no conflicts are 
  3359.      * possible.
  3360.      */
  3361.     record_address_regs_used ( const0_rtx );
  3362.  
  3363.     /* decrement the number of uses at the target label. */
  3364.  
  3365.     -- LABEL_NUSES ( operands[1] );
  3366.  
  3367.     return \"\";
  3368.     }
  3369.  
  3370.     /* record potential r/n register conflicts. */
  3371.     record_address_regs_used ( scan );
  3372.  
  3373.     if ( which_alternative )
  3374.     {
  3375.     return \"do    #%c0,%l1\";
  3376.     }
  3377.     else
  3378.     {
  3379.     if ( IS_SRC_OR_MPY_P ( REGNO ( operands[0] )))
  3380.     {
  3381.         return \"do    %0,%l1\";
  3382.     }
  3383.     else
  3384.     {
  3385.         return \"do    %e0,%l1\";
  3386.     }
  3387.     }
  3388. }" )
  3389.  
  3390. ;; This shape should match the back-branch insn and produce no real code.
  3391. ;; It is a placeholder so that the compiler knows that the do loop target
  3392. ;; label is implicitly a branch.
  3393.  
  3394. ( define_insn "od"
  3395.   [ ( parallel 
  3396.       [ ( clobber ( cc0 ))
  3397.     ( set ( pc ) ( match_operand 0 "" "" ))
  3398.       ] )
  3399.   ]
  3400.   ""
  3401.   "*
  3402. {
  3403.     rtx scan = PREV_INSN ( insn );
  3404.     
  3405.     while ( scan && 
  3406.        (( INSN != GET_CODE ( scan )) || 
  3407.         /* ignore latent nop insns! */
  3408.         ( const0_rtx == PATTERN ( scan ))) &&
  3409.        ( JUMP_INSN != GET_CODE ( scan )))
  3410.     {
  3411.     scan = PREV_INSN ( scan );
  3412.     }
  3413.     if ( ! scan )
  3414.     {
  3415.     /* od without corresponding do ! */
  3416.     abort ( );
  3417.     }
  3418.     if ( JUMP_INSN == GET_CODE ( scan ))
  3419.     {
  3420.     /* pop the stack - no chance of conflict. */
  3421.     (void) conflicting_address_regs_set_p ( const0_rtx );
  3422.     
  3423.     /* but hey- auto bonejob! we can't have a jmp as the last insn
  3424.        within the DO! */
  3425.  
  3426.     return \"nop\";
  3427.     }
  3428.     if ( INSN == GET_CODE ( scan ))
  3429.     {
  3430.     /* if we have a conflict, emit a noop to sw interlock. */
  3431.     if ( conflicting_address_regs_set_p ( scan ))
  3432.     {
  3433.         return \"nop\";
  3434.     }
  3435.     }
  3436.     return \"\";
  3437. }" )
  3438.  
  3439. ( define_insn ""
  3440.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=D,D" )
  3441.                ( match_operand:SI 1 "general_operand" "i,!*D*S*A" ))
  3442.          ( clobber 
  3443.            ( match_operand:SI 2 "register_operand" "=*D*S*A,*D*S*A" ))
  3444.          ])
  3445.   ]
  3446.   ""
  3447.   "*
  3448. {
  3449.     switch ( which_alternative )
  3450.     {
  3451.     case 0:
  3452.     if ( 0 == INTVAL ( operands[1] ))
  3453.     {
  3454.         return \"clr    %0\";
  3455.     }
  3456.     else
  3457.     {
  3458.         return \"move    #>1,%0\";
  3459.     }
  3460.  
  3461.     case 1:
  3462.     if ( DST_REGS == REGNO_REG_CLASS ( REGNO ( operands[1] )))
  3463.     {
  3464.         return \"move    %e1,%0\";
  3465.     }
  3466.     else
  3467.     {
  3468.         return \"move    %1,%0\";
  3469.     }
  3470.     }
  3471. }" )
  3472.  
  3473. ( define_expand "seq"
  3474.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3475.       ( eq ( cc0 ) ( const_int 0 ))) ]
  3476.   ""
  3477.   "
  3478. {
  3479.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3480.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3481.                gen_rtx ( EQ, VOIDmode, cc0_rtx, const0_rtx ));
  3482.         
  3483.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3484.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3485.     DONE;
  3486. }" )
  3487.     
  3488. ( define_insn ""
  3489.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3490.                ( eq ( cc0 ) ( const_int 0 )))
  3491.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3492.          ])
  3493.   ]
  3494.   ""
  3495.   "move    #>1,%1\;move    #0,%0\;teq    %1,%0" )
  3496.  
  3497. ( define_insn "beq"
  3498.   [ ( set ( pc )
  3499.       ( if_then_else ( eq ( cc0 )
  3500.                   ( const_int 0 ) )
  3501.              ( label_ref ( match_operand 0 "" "" ) )
  3502.              ( pc ) ) ) ]
  3503.   ""
  3504.   "jeq    %l0" )
  3505.  
  3506. ( define_expand "sequ"
  3507.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3508.       ( equ ( cc0 ) ( const_int 0 ))) ]
  3509.   ""
  3510.   "
  3511. {
  3512.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3513.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3514.                gen_rtx ( EQU, VOIDmode, cc0_rtx, const0_rtx ));
  3515.         
  3516.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3517.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3518.     DONE;
  3519. }" )
  3520.     
  3521. ( define_insn ""
  3522.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3523.                ( equ ( cc0 ) ( const_int 0 )))
  3524.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3525.          ])
  3526.   ]
  3527.   ""
  3528.   "move    #>1,%1\;move    #0,%0\;teq    %1,%0" )
  3529.  
  3530. ( define_insn "bequ"
  3531.   [ ( set ( pc )
  3532.       ( if_then_else ( equ ( cc0 )
  3533.                   ( const_int 0 ) )
  3534.              ( label_ref ( match_operand 0 "" "" ) )
  3535.              ( pc ) ) ) ]
  3536.   ""
  3537.   "jeq    %l0" )
  3538.  
  3539. ( define_expand "sne"
  3540.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3541.       ( ne ( cc0 ) ( const_int 0 ))) ]
  3542.   ""
  3543.   "
  3544. {
  3545.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3546.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3547.                gen_rtx ( NE, VOIDmode, cc0_rtx, const0_rtx ));
  3548.         
  3549.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3550.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3551.     DONE;
  3552. }" )
  3553.     
  3554. ( define_insn ""
  3555.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3556.                ( ne ( cc0 ) ( const_int 0 )))
  3557.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3558.          ])
  3559.   ]
  3560.   ""
  3561.   "move    #>1,%1\;move    #0,%0\;tne    %1,%0" )
  3562.  
  3563. ( define_insn "bne"
  3564.   [ ( set ( pc )
  3565.       ( if_then_else ( ne ( cc0 )
  3566.                   ( const_int 0 ) )
  3567.              ( label_ref ( match_operand 0 "" "" ) )
  3568.              ( pc ) ) ) ]
  3569.   ""
  3570.   "jne    %l0" )
  3571.  
  3572. ( define_expand "sneu"
  3573.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3574.       ( neu ( cc0 ) ( const_int 0 ))) ]
  3575.   ""
  3576.   "
  3577. {
  3578.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3579.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3580.                gen_rtx ( NEU, VOIDmode, cc0_rtx, const0_rtx ));
  3581.         
  3582.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3583.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3584.     DONE;
  3585. }" )
  3586.     
  3587. ( define_insn ""
  3588.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3589.                ( neu ( cc0 ) ( const_int 0 )))
  3590.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3591.          ])
  3592.   ]
  3593.   ""
  3594.   "move    #>1,%1\;move    #0,%0\;tne    %1,%0" )
  3595.  
  3596. ( define_insn "bneu"
  3597.   [ ( set ( pc )
  3598.       ( if_then_else ( neu ( cc0 )
  3599.                   ( const_int 0 ) )
  3600.              ( label_ref ( match_operand 0 "" "" ) )
  3601.              ( pc ) ) ) ]
  3602.   ""
  3603.   "jne    %l0" )
  3604.  
  3605. ( define_expand "sgt"
  3606.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3607.       ( gt ( cc0 ) ( const_int 0 ))) ]
  3608.   ""
  3609.   "
  3610. {
  3611.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3612.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3613.                gen_rtx ( GT, VOIDmode, cc0_rtx, const0_rtx ));
  3614.         
  3615.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3616.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3617.     DONE;
  3618. }" )
  3619.     
  3620. ( define_insn ""
  3621.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3622.                ( gt ( cc0 ) ( const_int 0 )))
  3623.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3624.          ])
  3625.   ]
  3626.   ""
  3627.   "move    #>1,%1\;move    #0,%0\;tgt    %1,%0" )
  3628.  
  3629. ( define_insn "bgt"
  3630.   [ ( set ( pc )
  3631.       ( if_then_else ( gt ( cc0 )
  3632.                   ( const_int 0 ) )
  3633.              ( label_ref ( match_operand 0 "" "" ) )
  3634.              ( pc ) ) ) ]
  3635.   ""
  3636.   "jgt    %l0" )
  3637.  
  3638. ( define_expand "sgtu"
  3639.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3640.       ( gtu ( cc0 ) ( const_int 0 ))) ]
  3641.   ""
  3642.   "
  3643. {
  3644.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3645.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3646.                gen_rtx ( GTU, VOIDmode, cc0_rtx, const0_rtx ));
  3647.         
  3648.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3649.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3650.     DONE;
  3651. }" )
  3652.     
  3653. ( define_insn ""
  3654.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3655.                ( gtu ( cc0 ) ( const_int 0 )))
  3656.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3657.          ])
  3658.   ]
  3659.   ""
  3660.   "move    #>1,%1\;move    #0,%0\;tgt    %1,%0" )
  3661.  
  3662. ( define_insn "bgtu"
  3663.   [ ( set ( pc )
  3664.       ( if_then_else ( gtu ( cc0 )
  3665.                    ( const_int 0 ) )
  3666.              ( label_ref ( match_operand 0 "" "" ) )
  3667.              ( pc ) ) ) ]
  3668.   ""
  3669.   "jgt    %l0" )
  3670.  
  3671. ( define_expand "slt"
  3672.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3673.       ( lt ( cc0 ) ( const_int 0 ))) ]
  3674.   ""
  3675.   "
  3676. {
  3677.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3678.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3679.                gen_rtx ( LT, VOIDmode, cc0_rtx, const0_rtx ));
  3680.         
  3681.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3682.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3683.     DONE;
  3684. }" )
  3685.     
  3686. ( define_insn ""
  3687.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3688.                ( lt ( cc0 ) ( const_int 0 )))
  3689.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3690.          ])
  3691.   ]
  3692.   ""
  3693.   "move    #>1,%1\;move    #0,%0\;tlt    %1,%0" )
  3694.  
  3695. ( define_insn "blt"
  3696.   [ ( set ( pc )
  3697.       ( if_then_else ( lt ( cc0 )
  3698.                   ( const_int 0 ) )
  3699.              ( label_ref ( match_operand 0 "" "" ) )
  3700.              ( pc ) ) ) ]
  3701.   ""
  3702.   "jlt    %l0" )
  3703.  
  3704. ( define_expand "sltu"
  3705.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3706.       ( ltu ( cc0 ) ( const_int 0 ))) ]
  3707.   ""
  3708.   "
  3709. {
  3710.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3711.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3712.                gen_rtx ( LTU, VOIDmode, cc0_rtx, const0_rtx ));
  3713.         
  3714.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3715.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3716.     DONE;
  3717. }" )
  3718.     
  3719. ( define_insn ""
  3720.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3721.                ( ltu ( cc0 ) ( const_int 0 )))
  3722.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3723.          ])
  3724.   ]
  3725.   ""
  3726.   "move    #>1,%1\;move    #0,%0\;tlt    %1,%0" )
  3727.  
  3728. ( define_insn "bltu"
  3729.   [ ( set ( pc )
  3730.       ( if_then_else ( ltu ( cc0 )
  3731.                    ( const_int 0 ) )
  3732.              ( label_ref ( match_operand 0 "" "" ) )
  3733.              ( pc ) ) ) ]
  3734.   ""
  3735.   "jlt    %l0" )
  3736.  
  3737. ( define_expand "sge"
  3738.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3739.       ( ge ( cc0 ) ( const_int 0 ))) ]
  3740.   ""
  3741.   "
  3742. {
  3743.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3744.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3745.                gen_rtx ( GE, VOIDmode, cc0_rtx, const0_rtx ));
  3746.         
  3747.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3748.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3749.     DONE;
  3750. }" )
  3751.     
  3752. ( define_insn ""
  3753.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3754.                ( ge ( cc0 ) ( const_int 0 )))
  3755.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3756.          ])
  3757.   ]
  3758.   ""
  3759.   "move    #>1,%1\;move    #0,%0\;tge    %1,%0" )
  3760.  
  3761. ( define_insn "bge"
  3762.   [ ( set ( pc )
  3763.       ( if_then_else ( ge ( cc0 )
  3764.                   ( const_int 0 ) )
  3765.              ( label_ref ( match_operand 0 "" "" ) )
  3766.              ( pc ) ) ) ]
  3767.   ""
  3768.   "jge    %l0" )
  3769.  
  3770. ( define_expand "sgeu"
  3771.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3772.       ( geu ( cc0 ) ( const_int 0 ))) ]
  3773.   ""
  3774.   "
  3775. {
  3776.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3777.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3778.                gen_rtx ( GEU, VOIDmode, cc0_rtx, const0_rtx ));
  3779.         
  3780.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3781.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3782.     DONE;
  3783. }" )
  3784.     
  3785. ( define_insn ""
  3786.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3787.                ( geu ( cc0 ) ( const_int 0 )))
  3788.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3789.          ])
  3790.   ]
  3791.   ""
  3792.   "move    #>1,%1\;move    #0,%0\;tge    %1,%0" )
  3793.  
  3794. ( define_insn "bgeu"
  3795.   [ ( set ( pc )
  3796.       ( if_then_else ( geu ( cc0 )
  3797.                    ( const_int 0 ) )
  3798.              ( label_ref ( match_operand 0 "" "" ) )
  3799.              ( pc ) ) ) ]
  3800.   ""
  3801.   "jge    %l0" )
  3802.  
  3803. ( define_expand "sle"
  3804.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3805.       ( le ( cc0 ) ( const_int 0 ))) ]
  3806.   ""
  3807.   "
  3808. {
  3809.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3810.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3811.                gen_rtx ( LE, VOIDmode, cc0_rtx, const0_rtx ));
  3812.         
  3813.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3814.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3815.     DONE;
  3816. }" )
  3817.     
  3818. ( define_insn ""
  3819.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3820.                ( le ( cc0 ) ( const_int 0 )))
  3821.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3822.          ])
  3823.   ]
  3824.   ""
  3825.   "move    #>1,%1\;move    #0,%0\;tle    %1,%0" )
  3826.  
  3827. ( define_insn "ble"
  3828.   [ ( set ( pc )
  3829.       ( if_then_else ( le ( cc0 )
  3830.                   ( const_int 0 ) )
  3831.              ( label_ref ( match_operand 0 "" "" ) )
  3832.              ( pc ) ) ) ]
  3833.   ""
  3834.   "jle    %l0" )
  3835.  
  3836. ( define_expand "sleu"
  3837.   [ ( set ( match_operand:SI 0 "register_operand" "=D" )
  3838.       ( leu ( cc0 ) ( const_int 0 ))) ]
  3839.   ""
  3840.   "
  3841. {
  3842.     rtx clobber_exp = gen_rtx ( CLOBBER, VOIDmode, gen_reg_rtx ( SImode ));
  3843.     rtx set_exp = gen_rtx ( SET, VOIDmode, operands[0],
  3844.                gen_rtx ( LEU, VOIDmode, cc0_rtx, const0_rtx ));
  3845.         
  3846.     emit_insn ( gen_rtx ( PARALLEL, VOIDmode,
  3847.              gen_rtvec ( 2, set_exp, clobber_exp )));
  3848.     DONE;
  3849. }" )
  3850.     
  3851. ( define_insn ""
  3852.   [ ( parallel [ ( set ( match_operand:SI 0 "register_operand" "=&D" )
  3853.                ( leu ( cc0 ) ( const_int 0 )))
  3854.          ( clobber ( match_operand:SI 1 "register_operand" "=*S*D" ))
  3855.          ])
  3856.   ]
  3857.   ""
  3858.   "move    #>1,%1\;move    #0,%0\;tle    %1,%0" )
  3859.  
  3860. ( define_insn "bleu"
  3861.   [ ( set ( pc )
  3862.       ( if_then_else ( leu ( cc0 )
  3863.                    ( const_int 0 ) )
  3864.              ( label_ref ( match_operand 0 "" "" ) )
  3865.              ( pc ) ) ) ]
  3866.   ""
  3867.   "jle    %l0" )
  3868.  
  3869.  
  3870. ;;
  3871. ;;  ...........................................................................
  3872. ;;
  3873. ;;          CONDITIONAL JUMPS WITH INVERTED REGISTER ALLOCATION
  3874. ;;
  3875. ;;  ...........................................................................
  3876. ;;
  3877.  
  3878. ( define_insn ""
  3879.   [ ( set ( pc )
  3880.       ( if_then_else ( eq ( cc0 )
  3881.                   ( const_int 0 ) )
  3882.              ( pc )
  3883.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3884.   ""
  3885.   "jne    %l0" )
  3886.  
  3887. ( define_insn ""
  3888.   [ ( set ( pc )
  3889.       ( if_then_else ( equ ( cc0 )
  3890.                      ( const_int 0 ) )
  3891.              ( pc )
  3892.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3893.   ""
  3894.   "jne    %l0" )
  3895.  
  3896. ( define_insn ""
  3897.   [ ( set ( pc )
  3898.       ( if_then_else ( ne ( cc0 )
  3899.                   ( const_int 0 ) )
  3900.              ( pc )
  3901.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3902.   ""
  3903.   "jeq    %l0" )
  3904.  
  3905. ( define_insn ""
  3906.   [ ( set ( pc )
  3907.       ( if_then_else ( neu ( cc0 )
  3908.                    ( const_int 0 ) )
  3909.              ( pc )
  3910.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3911.   ""
  3912.   "jeq    %l0" )
  3913.  
  3914. ( define_insn ""
  3915.   [ ( set ( pc )
  3916.       ( if_then_else ( gt ( cc0 )
  3917.                   ( const_int 0 ) )
  3918.              ( pc )
  3919.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3920.   ""
  3921.   "jle    %l0" )
  3922.  
  3923. ( define_insn ""
  3924.   [ ( set ( pc )
  3925.       ( if_then_else ( gtu ( cc0 )
  3926.                    ( const_int 0 ) )
  3927.              ( pc )
  3928.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3929.   ""
  3930.   "jle    %l0" )
  3931.  
  3932. ( define_insn ""
  3933.   [ ( set ( pc )
  3934.       ( if_then_else ( lt ( cc0 )
  3935.                   ( const_int 0 ) )
  3936.              ( pc )
  3937.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3938.   ""
  3939.   "jge    %l0" )
  3940.  
  3941. ( define_insn ""
  3942.   [ ( set ( pc )
  3943.       ( if_then_else ( ltu ( cc0 )
  3944.                    ( const_int 0 ) )
  3945.              ( pc )
  3946.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3947.   ""
  3948.   "jge    %l0" )
  3949.  
  3950. ( define_insn ""
  3951.   [ ( set ( pc )
  3952.       ( if_then_else ( ge ( cc0 )
  3953.                   ( const_int 0 ) )
  3954.              ( pc )
  3955.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3956.   ""
  3957.   "jlt    %l0" )
  3958.  
  3959. ( define_insn ""
  3960.   [ ( set ( pc )
  3961.       ( if_then_else ( geu ( cc0 )
  3962.                    ( const_int 0 ) )
  3963.              ( pc )
  3964.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3965.   ""
  3966.   "jlt    %l0" )
  3967.  
  3968.  
  3969. ( define_insn ""
  3970.   [ ( set ( pc )
  3971.       ( if_then_else ( le ( cc0 )
  3972.                   ( const_int 0 ) )
  3973.              ( pc )
  3974.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3975.   ""
  3976.   "jgt    %l0" )
  3977.  
  3978.  
  3979. ( define_insn ""
  3980.   [ ( set ( pc )
  3981.       ( if_then_else ( leu ( cc0 )
  3982.                    ( const_int 0 ) )
  3983.              ( pc )
  3984.              ( label_ref ( match_operand 0 "" "" ) ) ) ) ]
  3985.   ""
  3986.   "jgt    %l0" )
  3987.  
  3988.  
  3989. ;;
  3990. ;;  ...........................................................................
  3991. ;;
  3992. ;;          CONDITIONALY STORE ZERO OR NON-ZERO
  3993. ;;
  3994. ;;  ...........................................................................
  3995. ;;
  3996.  
  3997. ;;
  3998. ;;  ...........................................................................
  3999. ;;
  4000. ;;          UNCONDITIONAL JUMP
  4001. ;;
  4002. ;;  ...........................................................................
  4003. ;;
  4004.  
  4005. ( define_insn "jump"
  4006.   [ ( set ( pc )
  4007.       ( label_ref ( match_operand 0 "" "" ) ) ) ]
  4008.   ""
  4009.   "jmp    %l0" )
  4010.  
  4011.  
  4012. ;;
  4013. ;;  ...........................................................................
  4014. ;;
  4015. ;;          TABLE JUMP ( SWITCH IMPLEMENTATION )
  4016. ;;
  4017. ;;  ...........................................................................
  4018. ;;
  4019.  
  4020. ( define_insn "tablejump"
  4021.   [ ( set ( pc ) ( match_operand:PSI 0 "register_operand" "A" ) )
  4022.     ( use ( label_ref ( match_operand 1 "" "" ) ) ) ]
  4023.   ""
  4024.   "jmp    (%0)" )
  4025.  
  4026.  
  4027. ;;
  4028. ;;  ...........................................................................
  4029. ;;
  4030. ;;          SUBROUTINE CALLS
  4031. ;;
  4032. ;;  ...........................................................................
  4033. ;;
  4034.  
  4035. ( define_expand "call"
  4036.   [ ( call ( match_operand:PSI 0 "general_operand" "mA" )
  4037.        ( match_operand:SI 1 "immediate_operand" "i" ))
  4038.   ]
  4039.   ""
  4040.   "
  4041. {
  4042.     emit_insn ( 
  4043.            gen_rtx ( PARALLEL,
  4044.             VOIDmode,
  4045.             gen_rtvec ( 1,
  4046.                    gen_rtx ( CALL, 
  4047.                         VOIDmode,
  4048.                         operands[0], operands[1] ))));
  4049.     DONE;
  4050. }" )
  4051.  
  4052. ( define_insn ""
  4053.   [ ( parallel [ ( call ( match_operand:PSI 0 "general_operand" "mA" )
  4054.             ( match_operand:SI 1 "immediate_operand" "i" )) ] )
  4055.   ]
  4056.   ""
  4057.   "*
  4058. {
  4059.     clear_n_reg_values ( );
  4060.     
  4061.     switch ( INTVAL ( operands[1] ))
  4062.     {
  4063.     case 0:
  4064.     return \"jsr    %0\";
  4065.     
  4066.     case 1:
  4067.     return \"jsr    %0\;move    (r6)-\";
  4068.     
  4069.     case 2:
  4070.     return \"jsr    %0\;move    (r6)-\;move    (r6)-\";
  4071.     
  4072.     default:
  4073.     return \"jsr    %0\;move    #%p1,n6\;move    (r6)-n6\";
  4074.     }
  4075. }" )
  4076.  
  4077. ( define_expand "call_value"
  4078.   [ ( set ( match_operand 0 "" "" )
  4079.       ( call ( match_operand:PSI 1 "general_operand" "mA" )
  4080.          ( match_operand:SI 2 "immediate_operand" "i" )))
  4081.   ]
  4082.   ""
  4083.   "
  4084. {
  4085.     emit_insn ( 
  4086.            gen_rtx ( PARALLEL, VOIDmode,
  4087.             gen_rtvec ( 1,
  4088.                    gen_rtx ( SET, VOIDmode,
  4089.                         operands[0],
  4090.                         gen_rtx ( CALL, VOIDmode,
  4091.                              operands[1],
  4092.                              operands[2] )))));
  4093.     DONE;
  4094. }" )
  4095.  
  4096. ( define_insn ""
  4097.   [ ( parallel [ ( set ( match_operand 0 "" "" )
  4098.                ( call ( match_operand:PSI 1 "general_operand" "mA" )
  4099.                   ( match_operand:SI 2 "immediate_operand" "i" )))
  4100.            ] )
  4101.   ]
  4102.   ""
  4103.   "*
  4104. {
  4105.     clear_n_reg_values ( );
  4106.     
  4107.     switch ( INTVAL ( operands[2] ))
  4108.     {
  4109.     case 0:
  4110.     return \"jsr    %1\";
  4111.     
  4112.     case 1:
  4113.     return \"jsr    %1\;move    (r6)-\";
  4114.     
  4115.     case 2:
  4116.     return \"jsr    %1\;move    (r6)-\;move    (r6)-\";
  4117.     
  4118.     default:
  4119.     return \"jsr    %1\;move    #%p2,n6\;move    (r6)-n6\";
  4120.     }
  4121. }" )
  4122.  
  4123.  
  4124. ;;
  4125. ;;  ...........................................................................
  4126. ;;
  4127. ;;          NOP
  4128. ;;
  4129. ;;  ...........................................................................
  4130. ;;
  4131.  
  4132. ( define_insn "nop"
  4133.   [ ( const_int 0 ) ]
  4134.   ""
  4135.   "*
  4136. {
  4137.     rtx peek = PREV_INSN ( insn );
  4138.     
  4139.     while (( peek ) && 
  4140.        (( NOTE == GET_CODE ( peek )) ||
  4141.         (( JUMP_INSN == GET_CODE ( peek )) &&
  4142.          ( PARALLEL == GET_CODE ( PATTERN ( peek ))))))
  4143.     {
  4144.     peek = PREV_INSN ( peek );
  4145.     }
  4146.     if (( ! peek ) || ( CODE_LABEL != GET_CODE ( peek )) ||
  4147.     ( ! LABEL_NUSES ( peek )))
  4148.     {
  4149.     return \"\";
  4150.     }
  4151.     
  4152.     peek = NEXT_INSN ( insn );
  4153.     while (( peek ) && 
  4154.        (( NOTE == GET_CODE ( peek )) ||
  4155.         (( JUMP_INSN == GET_CODE ( peek )) &&
  4156.          ( PARALLEL == GET_CODE ( PATTERN ( peek ))))))
  4157.     {
  4158.     peek = NEXT_INSN ( peek );
  4159.     }
  4160.     if (( ! peek ) || 
  4161.     ( ! LABEL_NUSES ( peek )) ||
  4162.     (( CODE_LABEL != GET_CODE ( peek )) && 
  4163.      ( const0_rtx != PATTERN ( peek ))))
  4164.     {
  4165.     return \"\";
  4166.     }
  4167.  
  4168.     return \"nop\";
  4169. }" )
  4170.  
  4171. ;; This insn is needed because jump.c doesn't realize that this is really
  4172. ;; a nop.
  4173.  
  4174. ( define_insn "" [ ( set ( pc ) ( pc )) ] "" "" )
  4175.  
  4176. ( define_insn "probe" 
  4177.   [ ( parallel [ ( const_int 0 ) ] ) ]
  4178.   ""
  4179.   "*
  4180. {
  4181.     if ( TARGET_STACK_CHECK )
  4182.     {
  4183.     return \"jsr    F__stack_check\";
  4184.     }
  4185.     else
  4186.     {
  4187.     return \"\";
  4188.     }
  4189. }" )
  4190.  
  4191. ;;
  4192. ;;  ...........................................................................
  4193. ;;
  4194. ;;          PEEPHOLE OPTIMIZATIONS
  4195. ;;
  4196. ;;  ...........................................................................
  4197. ;;
  4198.  
  4199. ;; this sequence can be introduced by the do loop generation code. a 
  4200. ;; reasonable data flow analysis and optimization phase will (in the future)
  4201. ;; clean it up.
  4202.  
  4203. ( define_peephole 
  4204.   [ ( set ( match_operand:SI 0 "register_operand" "=*D" )
  4205.       ( minus:SI ( match_operand:SI 1 "register_operand" "0" )
  4206.              ( match_operand:SI 2 "register_operand" "*S*D" )))
  4207.     ( set ( match_dup 0 )
  4208.       ( plus:SI ( match_dup 1 )
  4209.             ( match_dup 2 )))
  4210.   ]
  4211.   "( ! rtx_equal_p (operands[0], operands[2] ))" 
  4212.   "" )
  4213.  
  4214. ;;- Local variables:
  4215. ;;- mode:emacs-lisp
  4216. ;;- comment-start: ";;- "
  4217. ;;- eval: ( set-syntax-table ( copy-sequence ( syntax-table ) ) )
  4218. ;;- eval: ( modify-syntax-entry ?[ "(]" )
  4219. ;;- eval: ( modify-syntax-entry ?] ")[" )
  4220. ;;- eval: ( modify-syntax-entry ?{ "(}" )
  4221. ;;- eval: ( modify-syntax-entry ?} "){" )
  4222. ;;- End:
  4223.  
  4224.